diff options
Diffstat (limited to 'src')
414 files changed, 27882 insertions, 16835 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 72d79619b2..7fdc766e1c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,7 +14,7 @@ $(LIBLEVELDB): $(LIBMEMENV) $(LIBLEVELDB) $(LIBMEMENV): @echo "Building LevelDB ..." && $(MAKE) -C $(@D) $(@F) CXX="$(CXX)" \ CC="$(CC)" PLATFORM=$(TARGET_OS) AR="$(AR)" $(LEVELDB_TARGET_FLAGS) \ - OPT="$(CXXFLAGS) $(CPPFLAGS)" + OPT="$(CXXFLAGS) $(CPPFLAGS) -D__STDC_LIMIT_MACROS" endif BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config @@ -48,6 +48,9 @@ if ENABLE_WALLET BITCOIN_INCLUDES += $(BDB_CPPFLAGS) EXTRA_LIBRARIES += libbitcoin_wallet.a endif +if ENABLE_ZMQ +EXTRA_LIBRARIES += libbitcoin_zmq.a +endif if BUILD_BITCOIN_LIBS lib_LTLIBRARIES = libbitcoinconsensus.la @@ -77,8 +80,8 @@ BITCOIN_CORE_H = \ base58.h \ bloom.h \ chain.h \ - chainparamsbase.h \ chainparams.h \ + chainparamsbase.h \ chainparamsseeds.h \ checkpoints.h \ checkqueue.h \ @@ -86,38 +89,49 @@ BITCOIN_CORE_H = \ coincontrol.h \ coins.h \ compat.h \ + compat/byteswap.h \ + compat/endian.h \ + compat/sanity.h \ compressor.h \ consensus/consensus.h \ consensus/params.h \ + consensus/validation.h \ core_io.h \ - wallet/db.h \ + core_memusage.h \ eccryptoverify.h \ ecwrapper.h \ hash.h \ + httprpc.h \ + httpserver.h \ init.h \ key.h \ keystore.h \ leveldbwrapper.h \ limitedmap.h \ main.h \ + memusage.h \ merkleblock.h \ miner.h \ mruset.h \ - netbase.h \ net.h \ + netbase.h \ noui.h \ + policy/fees.h \ + policy/policy.h \ pow.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_error.h \ script/script.h \ + script/script_error.h \ script/sigcache.h \ script/sign.h \ script/standard.h \ @@ -143,23 +157,15 @@ BITCOIN_CORE_H = \ validationinterface.h \ version.h \ wallet/crypter.h \ - wallet/walletdb.h \ + wallet/db.h \ wallet/wallet.h \ wallet/wallet_ismine.h \ - compat/byteswap.h \ - compat/endian.h \ - compat/sanity.h - -JSON_H = \ - json/json_spirit.h \ - json/json_spirit_error_position.h \ - json/json_spirit_reader.h \ - json/json_spirit_reader_template.h \ - json/json_spirit_stream_reader.h \ - json/json_spirit_utils.h \ - json/json_spirit_value.h \ - json/json_spirit_writer.h \ - json/json_spirit_writer_template.h + wallet/walletdb.h \ + zmq/zmqabstractnotifier.h \ + zmq/zmqconfig.h\ + zmq/zmqnotificationinterface.h \ + zmq/zmqpublishnotifier.h + obj/build.h: FORCE @$(MKDIR_P) $(builddir)/obj @@ -168,13 +174,15 @@ obj/build.h: FORCE libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h # server: shared between bitcoind and bitcoin-qt -libbitcoin_server_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) +libbitcoin_server_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) libbitcoin_server_a_SOURCES = \ addrman.cpp \ alert.cpp \ bloom.cpp \ chain.cpp \ checkpoints.cpp \ + httprpc.cpp \ + httpserver.cpp \ init.cpp \ leveldbwrapper.cpp \ main.cpp \ @@ -182,6 +190,8 @@ libbitcoin_server_a_SOURCES = \ miner.cpp \ net.cpp \ noui.cpp \ + policy/fees.cpp \ + policy/policy.cpp \ pow.cpp \ rest.cpp \ rpcblockchain.cpp \ @@ -195,9 +205,19 @@ libbitcoin_server_a_SOURCES = \ txdb.cpp \ txmempool.cpp \ validationinterface.cpp \ - $(JSON_H) \ $(BITCOIN_CORE_H) +if ENABLE_ZMQ +LIBBITCOIN_ZMQ=libbitcoin_zmq.a + +libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) +libbitcoin_zmq_a_SOURCES = \ + zmq/zmqabstractnotifier.cpp \ + zmq/zmqnotificationinterface.cpp \ + zmq/zmqpublishnotifier.cpp +endif + + # wallet: shared between bitcoind and bitcoin-qt, but only linked # when wallet enabled libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES) @@ -214,39 +234,37 @@ libbitcoin_wallet_a_SOURCES = \ # crypto primitives library crypto_libbitcoin_crypto_a_CPPFLAGS = $(BITCOIN_CONFIG_INCLUDES) crypto_libbitcoin_crypto_a_SOURCES = \ - crypto/sha1.cpp \ - crypto/sha256.cpp \ - crypto/sha512.cpp \ - crypto/hmac_sha256.cpp \ - crypto/hmac_sha512.cpp \ - crypto/ripemd160.cpp \ crypto/common.h \ - crypto/sha256.h \ - crypto/sha512.h \ + crypto/hmac_sha256.cpp \ crypto/hmac_sha256.h \ + crypto/hmac_sha512.cpp \ crypto/hmac_sha512.h \ + crypto/ripemd160.cpp \ + crypto/ripemd160.h \ + crypto/sha1.cpp \ crypto/sha1.h \ - crypto/ripemd160.h + crypto/sha256.cpp \ + crypto/sha256.h \ + crypto/sha512.cpp \ + crypto/sha512.h # univalue JSON library univalue_libbitcoin_univalue_a_SOURCES = \ univalue/univalue.cpp \ - univalue/univalue_read.cpp \ - univalue/univalue_write.cpp \ + univalue/univalue.h \ univalue/univalue_escapes.h \ - univalue/univalue.h + univalue/univalue_read.cpp \ + univalue/univalue_write.cpp # common: shared between bitcoind, and bitcoin-qt and non-server tools libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_common_a_SOURCES = \ - arith_uint256.cpp \ amount.cpp \ + arith_uint256.cpp \ base58.cpp \ chainparams.cpp \ coins.cpp \ compressor.cpp \ - primitives/block.cpp \ - primitives/transaction.cpp \ core_read.cpp \ core_write.cpp \ eccryptoverify.cpp \ @@ -255,13 +273,16 @@ libbitcoin_common_a_SOURCES = \ 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 \ - script/script_error.cpp \ $(BITCOIN_CORE_H) # util: shared between all executables. @@ -318,16 +339,19 @@ bitcoind_LDADD = \ $(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) -# +bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) # bitcoin-cli binary # bitcoin_cli_SOURCES = bitcoin-cli.cpp -bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES) +bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS @@ -336,10 +360,10 @@ endif bitcoin_cli_LDADD = \ $(LIBBITCOIN_CLI) \ - $(LIBBITCOIN_UTIL) \ - $(LIBSECP256K1) + $(LIBBITCOIN_UNIVALUE) \ + $(LIBBITCOIN_UTIL) -bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) +bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS) # # bitcoin-tx binary # @@ -347,6 +371,10 @@ bitcoin_tx_SOURCES = bitcoin-tx.cpp bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES) bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) +if TARGET_WINDOWS +bitcoin_tx_SOURCES += bitcoin-tx-res.rc +endif + bitcoin_tx_LDADD = \ $(LIBBITCOIN_UNIVALUE) \ $(LIBBITCOIN_COMMON) \ diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 31fe3a9f69..3330ed2890 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -87,7 +87,7 @@ QT_FORMS_UI = \ qt/forms/overviewpage.ui \ qt/forms/receivecoinsdialog.ui \ qt/forms/receiverequestdialog.ui \ - qt/forms/rpcconsole.ui \ + qt/forms/debugwindow.ui \ qt/forms/sendcoinsdialog.ui \ qt/forms/sendcoinsentry.ui \ qt/forms/signverifymessagedialog.ui \ @@ -97,6 +97,7 @@ QT_MOC_CPP = \ qt/moc_addressbookpage.cpp \ qt/moc_addresstablemodel.cpp \ qt/moc_askpassphrasedialog.cpp \ + qt/moc_bantablemodel.cpp \ qt/moc_bitcoinaddressvalidator.cpp \ qt/moc_bitcoinamountfield.cpp \ qt/moc_bitcoingui.cpp \ @@ -162,6 +163,7 @@ BITCOIN_QT_H = \ qt/addressbookpage.h \ qt/addresstablemodel.h \ qt/askpassphrasedialog.h \ + qt/bantablemodel.h \ qt/bitcoinaddressvalidator.h \ qt/bitcoinamountfield.h \ qt/bitcoingui.h \ @@ -185,13 +187,13 @@ BITCOIN_QT_H = \ qt/paymentrequestplus.h \ qt/paymentserver.h \ qt/peertablemodel.h \ + qt/platformstyle.h \ qt/qvalidatedlineedit.h \ qt/qvaluecombobox.h \ qt/receivecoinsdialog.h \ qt/receiverequestdialog.h \ qt/recentrequeststablemodel.h \ qt/rpcconsole.h \ - qt/scicon.h \ qt/sendcoinsdialog.h \ qt/sendcoinsentry.h \ qt/signverifymessagedialog.h \ @@ -256,9 +258,11 @@ RES_ICONS = \ qt/res/icons/tx_input.png \ qt/res/icons/tx_output.png \ qt/res/icons/tx_mined.png \ + qt/res/icons/warning.png \ qt/res/icons/verify.png BITCOIN_QT_CPP = \ + qt/bantablemodel.cpp \ qt/bitcoinaddressvalidator.cpp \ qt/bitcoinamountfield.cpp \ qt/bitcoingui.cpp \ @@ -272,10 +276,10 @@ BITCOIN_QT_CPP = \ qt/optionsdialog.cpp \ qt/optionsmodel.cpp \ qt/peertablemodel.cpp \ + qt/platformstyle.cpp \ qt/qvalidatedlineedit.cpp \ qt/qvaluecombobox.cpp \ qt/rpcconsole.cpp \ - qt/scicon.cpp \ qt/splashscreen.cpp \ qt/trafficgraphwidget.cpp \ qt/utilitydialog.cpp @@ -321,7 +325,7 @@ RES_MOVIES = $(wildcard qt/res/movies/spinner-*.png) BITCOIN_RC = qt/res/bitcoin-qt-res.rc BITCOIN_QT_INCLUDES = -I$(builddir)/qt -I$(srcdir)/qt -I$(srcdir)/qt/forms \ - -I$(builddir)/qt/forms + -I$(builddir)/qt/forms -DQT_NO_KEYWORDS qt_libbitcoinqt_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ $(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS) @@ -360,8 +364,12 @@ qt_bitcoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER) if ENABLE_WALLET qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET) 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) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ - $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) + $(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) qt_bitcoin_qt_LIBTOOLFLAGS = --tag CXX diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index c5392cf307..6554580bea 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -30,9 +30,13 @@ qt_test_test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER) if ENABLE_WALLET qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET) 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) $(LIBBITCOIN_UNIVALUE) $(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) + $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ + $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 9aec13ccef..cee35926a5 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -15,6 +15,8 @@ EXTRA_DIST += \ test/data/tx394b54bb.hex \ test/data/txcreate1.hex \ test/data/txcreate2.hex \ + test/data/txcreatedata1.hex \ + test/data/txcreatedata2.hex \ test/data/txcreatesign.hex JSON_TEST_FILES = \ @@ -50,6 +52,7 @@ BITCOIN_TESTS =\ test/getarg_tests.cpp \ test/hash_tests.cpp \ test/key_tests.cpp \ + test/limitedmap_tests.cpp \ test/main_tests.cpp \ test/mempool_tests.cpp \ test/miner_tests.cpp \ @@ -57,9 +60,12 @@ BITCOIN_TESTS =\ test/multisig_tests.cpp \ test/netbase_tests.cpp \ test/pmt_tests.cpp \ + test/policyestimator_tests.cpp \ test/pow_tests.cpp \ + test/reverselock_tests.cpp \ test/rpc_tests.cpp \ test/sanity_tests.cpp \ + test/scheduler_tests.cpp \ test/script_P2SH_tests.cpp \ test/script_tests.cpp \ test/scriptnum_tests.cpp \ @@ -71,6 +77,7 @@ BITCOIN_TESTS =\ test/test_bitcoin.h \ test/timedata_tests.cpp \ test/transaction_tests.cpp \ + test/txvalidationcache_tests.cpp \ test/uint256_tests.cpp \ test/univalue_tests.cpp \ test/util_tests.cpp @@ -93,6 +100,10 @@ endif test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static +if ENABLE_ZMQ +test_test_bitcoin_LDADD += $(ZMQ_LIBS) +endif + nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES) $(BITCOIN_TESTS): $(GENERATED_TEST_FILES) diff --git a/src/addrman.cpp b/src/addrman.cpp index c41ee3f9fc..ff1f7e9187 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -8,8 +8,6 @@ #include "serialize.h" #include "streams.h" -using namespace std; - int CAddrInfo::GetTriedBucket(const uint256& nKey) const { uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetKey()).GetHash().GetCheapHash(); @@ -68,7 +66,7 @@ double CAddrInfo::GetChance(int64_t nNow) const fChance *= 0.01; // deprioritize 66% after each failed attempt, but at most 1/28th to avoid the search taking forever or overly penalizing outages. - fChance *= pow(0.66, min(nAttempts, 8)); + fChance *= pow(0.66, std::min(nAttempts, 8)); return fChance; } @@ -258,7 +256,7 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60); int64_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60); if (addr.nTime && (!pinfo->nTime || pinfo->nTime < addr.nTime - nUpdateInterval - nTimePenalty)) - pinfo->nTime = max((int64_t)0, addr.nTime - nTimePenalty); + pinfo->nTime = std::max((int64_t)0, addr.nTime - nTimePenalty); // add services pinfo->nServices |= addr.nServices; @@ -283,7 +281,7 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP return false; } else { pinfo = Create(addr, source, &nId); - pinfo->nTime = max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty); + pinfo->nTime = std::max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty); nNew++; fNew = true; } @@ -343,8 +341,10 @@ CAddrInfo CAddrMan::Select_() while (1) { int nKBucket = GetRandInt(ADDRMAN_TRIED_BUCKET_COUNT); int nKBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE); - if (vvTried[nKBucket][nKBucketPos] == -1) - continue; + while (vvTried[nKBucket][nKBucketPos] == -1) { + nKBucket = (nKBucket + insecure_rand()) % ADDRMAN_TRIED_BUCKET_COUNT; + nKBucketPos = (nKBucketPos + insecure_rand()) % ADDRMAN_BUCKET_SIZE; + } int nId = vvTried[nKBucket][nKBucketPos]; assert(mapInfo.count(nId) == 1); CAddrInfo& info = mapInfo[nId]; @@ -358,8 +358,10 @@ CAddrInfo CAddrMan::Select_() while (1) { int nUBucket = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT); int nUBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE); - if (vvNew[nUBucket][nUBucketPos] == -1) - continue; + while (vvNew[nUBucket][nUBucketPos] == -1) { + nUBucket = (nUBucket + insecure_rand()) % ADDRMAN_NEW_BUCKET_COUNT; + nUBucketPos = (nUBucketPos + insecure_rand()) % ADDRMAN_BUCKET_SIZE; + } int nId = vvNew[nUBucket][nUBucketPos]; assert(mapInfo.count(nId) == 1); CAddrInfo& info = mapInfo[nId]; diff --git a/src/addrman.h b/src/addrman.h index 5badd4ef95..384b6cfdb9 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -17,8 +17,8 @@ #include <stdint.h> #include <vector> -/** - * Extended statistics about a CAddress +/** + * Extended statistics about a CAddress */ class CAddrInfo : public CAddress { @@ -105,15 +105,15 @@ public: /** Stochastic address manager * * Design goals: - * * Keep the address tables in-memory, and asynchronously dump the entire to able in peers.dat. + * * Keep the address tables in-memory, and asynchronously dump the entire table to peers.dat. * * Make sure no (localized) attacker can fill the entire table with his nodes/addresses. * * To that end: * * Addresses are organized into buckets. - * * Address that have not yet been tried go into 1024 "new" buckets. - * * Based on the address range (/16 for IPv4) of source of the information, 64 buckets are selected at random - * * The actual bucket is chosen from one of these, based on the range the address itself is located. - * * One single address can occur in up to 8 different buckets, to increase selection chances for addresses that + * * Addresses that have not yet been tried go into 1024 "new" buckets. + * * Based on the address range (/16 for IPv4) of the source of information, 64 buckets are selected at random. + * * The actual bucket is chosen from one of these, based on the range in which the address itself is located. + * * One single address can occur in up to 8 different buckets to increase selection chances for addresses that * are seen frequently. The chance for increasing this multiplicity decreases exponentially. * * When adding a new address to a full bucket, a randomly chosen entry (with a bias favoring less recently seen * ones) is removed from it first. @@ -231,7 +231,6 @@ protected: void Attempt_(const CService &addr, int64_t nTime); //! Select an address to connect to. - //! nUnkBias determines how much to favor new addresses over tried ones (min=0, max=100) CAddrInfo Select_(); #ifdef DEBUG_ADDRMAN @@ -266,7 +265,7 @@ public: * Notice that vvTried, mapAddr and vVector are never encoded explicitly; * they are instead reconstructed from the other information. * - * vvNew is serialized, but only used if ADDRMAN_UNKOWN_BUCKET_COUNT didn't change, + * vvNew is serialized, but only used if ADDRMAN_UNKNOWN_BUCKET_COUNT didn't change, * otherwise it is reconstructed as well. * * This format is more complex, but significantly smaller (at most 1.5 MiB), and supports @@ -459,7 +458,7 @@ public: } //! Return the number of (unique) addresses in all tables. - int size() + size_t size() const { return vRandom.size(); } @@ -532,7 +531,6 @@ public: /** * Choose an address to connect to. - * nUnkBias determines how much "new" entries are favored over "tried" ones (0-100). */ CAddrInfo Select() { diff --git a/src/alert.cpp b/src/alert.cpp index aa7ac748da..91e54a9178 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -11,6 +11,7 @@ #include "timedata.h" #include "ui_interface.h" #include "util.h" +#include "utilstrencodings.h" #include <stdint.h> #include <algorithm> @@ -50,7 +51,7 @@ std::string CUnsignedAlert::ToString() const BOOST_FOREACH(int n, setCancel) strSetCancel += strprintf("%d ", n); std::string strSetSubVer; - BOOST_FOREACH(std::string str, setSubVer) + BOOST_FOREACH(const std::string& str, setSubVer) strSetSubVer += "\"" + str + "\" "; return strprintf( "CAlert(\n" @@ -110,7 +111,7 @@ bool CAlert::Cancels(const CAlert& alert) const return (alert.nID <= nCancel || setCancel.count(alert.nID)); } -bool CAlert::AppliesTo(int nVersion, std::string strSubVerIn) const +bool CAlert::AppliesTo(int nVersion, const std::string& strSubVerIn) const { // TODO: rework for client-version-embedded-in-strSubVer ? return (IsInEffect() && diff --git a/src/alert.h b/src/alert.h index 746967c4af..4f9fff9181 100644 --- a/src/alert.h +++ b/src/alert.h @@ -97,7 +97,7 @@ public: uint256 GetHash() const; bool IsInEffect() const; bool Cancels(const CAlert& alert) const; - bool AppliesTo(int nVersion, std::string strSubVerIn) const; + bool AppliesTo(int nVersion, const std::string& strSubVerIn) const; bool AppliesToMe() const; bool RelayTo(CNode* pnode) const; bool CheckSignature(const std::vector<unsigned char>& alertKey) const; diff --git a/src/amount.cpp b/src/amount.cpp index 0a394c96fc..b469181984 100644 --- a/src/amount.cpp +++ b/src/amount.cpp @@ -7,6 +7,8 @@ #include "tinyformat.h" +const std::string CURRENCY_UNIT = "BTC"; + CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nSize) { if (nSize > 0) @@ -27,5 +29,5 @@ CAmount CFeeRate::GetFee(size_t nSize) const std::string CFeeRate::ToString() const { - return strprintf("%d.%08d BTC/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN); + return strprintf("%d.%08d %s/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN, CURRENCY_UNIT); } diff --git a/src/amount.h b/src/amount.h index 9212244a88..90e6b5aa8e 100644 --- a/src/amount.h +++ b/src/amount.h @@ -16,7 +16,17 @@ typedef int64_t CAmount; static const CAmount COIN = 100000000; static const CAmount CENT = 1000000; -/** No amount larger than this (in satoshi) is valid */ +extern const std::string CURRENCY_UNIT; + +/** No amount larger than this (in satoshi) is valid. + * + * Note that this constant is *not* the total money supply, which in Bitcoin + * currently happens to be less than 21,000,000 BTC for various reasons, but + * rather a sanity check. As this sanity check is used by consensus-critical + * validation code, the exact value of the MAX_MONEY constant is consensus + * critical; in unusual circumstances like a(nother) overflow bug that allowed + * for the creation of coins out of thin air modification could lead to a fork. + * */ static const CAmount MAX_MONEY = 21000000 * COIN; inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } diff --git a/src/base58.h b/src/base58.h index 8de90046a9..90014b9496 100644 --- a/src/base58.h +++ b/src/base58.h @@ -6,10 +6,10 @@ /** * Why base-58 instead of standard base-64 encoding? * - Don't want 0OIl characters that look the same in some fonts and - * could be used to create visually identical looking account numbers. - * - A string with non-alphanumeric characters is not as easily accepted as an account number. + * could be used to create visually identical looking data. + * - A string with non-alphanumeric characters is not as easily accepted as input. * - E-mail usually won't line-break if there's no punctuation to break at. - * - Double-clicking selects the whole number as one word if it's all alphanumeric. + * - Double-clicking selects the whole string as one word if it's all alphanumeric. */ #ifndef BITCOIN_BASE58_H #define BITCOIN_BASE58_H @@ -146,7 +146,10 @@ public: K GetKey() { K ret; - ret.Decode(&vchData[0], &vchData[Size]); + if (vchData.size() == Size) { + //if base58 encouded data not holds a ext key, return a !IsValid() key + ret.Decode(&vchData[0]); + } return ret; } @@ -154,6 +157,10 @@ public: SetKey(key); } + CBitcoinExtKeyBase(const std::string& strBase58c) { + SetString(strBase58c.c_str(), Params().Base58Prefix(Type).size()); + } + CBitcoinExtKeyBase() {} }; diff --git a/src/bitcoin-cli-res.rc b/src/bitcoin-cli-res.rc index 4ea1f38e47..1e4aa609bb 100644 --- a/src/bitcoin-cli-res.rc +++ b/src/bitcoin-cli-res.rc @@ -17,13 +17,13 @@ BEGIN BLOCK "040904E4" // U.S. English - multilingual (hex) BEGIN VALUE "CompanyName", "Bitcoin" - VALUE "FileDescription", "Bitcoin-cli (OSS RPC client for Bitcoin)" + VALUE "FileDescription", "bitcoin-cli (JSON-RPC client for Bitcoin Core)" VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoin-cli" 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-cli.exe" - VALUE "ProductName", "Bitcoin-cli" + VALUE "ProductName", "bitcoin-cli" VALUE "ProductVersion", VER_PRODUCTVERSION_STR END END diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 1269d7a119..7839b3b6b4 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -11,9 +11,18 @@ #include "utilstrencodings.h" #include <boost/filesystem/operations.hpp> +#include <stdio.h> + +#include <event2/event.h> +#include <event2/http.h> +#include <event2/buffer.h> +#include <event2/keyvalq_struct.h> + +#include "univalue/univalue.h" using namespace std; -using namespace json_spirit; + +static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900; std::string HelpMessageCli() { @@ -30,9 +39,7 @@ std::string HelpMessageCli() strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start")); strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections")); - - strUsage += HelpMessageGroup(_("SSL options: (see the Bitcoin Wiki for SSL setup instructions)")); - strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections")); + strUsage += HelpMessageOpt("-rpcclienttimeout=<n>", strprintf(_("Timeout during HTTP requests (default: %d)"), DEFAULT_HTTP_CLIENT_TIMEOUT)); return strUsage; } @@ -91,61 +98,119 @@ static bool AppInitRPC(int argc, char* argv[]) fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n"); return false; } + if (GetBoolArg("-rpcssl", false)) + { + fprintf(stderr, "Error: SSL mode for RPC (-rpcssl) is no longer supported.\n"); + return false; + } return true; } -Object CallRPC(const string& strMethod, const Array& params) + +/** Reply structure for request_done to fill in */ +struct HTTPReply { - if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "") - throw runtime_error(strprintf( - _("You must set rpcpassword=<password> in the configuration file:\n%s\n" - "If the file does not exist, create it with owner-readable-only file permissions."), - GetConfigFile().string().c_str())); - - // Connect to localhost - bool fUseSSL = GetBoolArg("-rpcssl", false); - boost::asio::io_service io_service; - boost::asio::ssl::context context(io_service, boost::asio::ssl::context::sslv23); - context.set_options(boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::no_sslv3); - boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sslStream(io_service, context); - SSLIOStreamDevice<boost::asio::ip::tcp> d(sslStream, fUseSSL); - boost::iostreams::stream< SSLIOStreamDevice<boost::asio::ip::tcp> > stream(d); - - const bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort()))); - if (!fConnected) - throw CConnectionFailed("couldn't connect to server"); + int status; + std::string body; +}; - // HTTP basic authentication - string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]); - map<string, string> mapRequestHeaders; - mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64; +static void http_request_done(struct evhttp_request *req, void *ctx) +{ + HTTPReply *reply = static_cast<HTTPReply*>(ctx); + + if (req == NULL) { + /* If req is NULL, it means an error occurred while connecting, but + * I'm not sure how to find out which one. We also don't really care. + */ + reply->status = 0; + return; + } - // Send request - string strRequest = JSONRPCRequest(strMethod, params, 1); - string strPost = HTTPPost(strRequest, mapRequestHeaders); - stream << strPost << std::flush; + reply->status = evhttp_request_get_response_code(req); - // Receive HTTP reply status - int nProto = 0; - int nStatus = ReadHTTPStatus(stream, nProto); + struct evbuffer *buf = evhttp_request_get_input_buffer(req); + if (buf) + { + size_t size = evbuffer_get_length(buf); + const char *data = (const char*)evbuffer_pullup(buf, size); + if (data) + reply->body = std::string(data, size); + evbuffer_drain(buf, size); + } +} + +UniValue CallRPC(const string& strMethod, const UniValue& params) +{ + std::string host = GetArg("-rpcconnect", "127.0.0.1"); + int port = GetArg("-rpcport", BaseParams().RPCPort()); + + // Create event base + struct event_base *base = event_base_new(); // TODO RAII + if (!base) + throw runtime_error("cannot create event_base"); + + // Synchronously look up hostname + struct evhttp_connection *evcon = evhttp_connection_base_new(base, NULL, host.c_str(), port); // TODO RAII + if (evcon == NULL) + throw runtime_error("create connection failed"); + evhttp_connection_set_timeout(evcon, GetArg("-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT)); + + HTTPReply response; + struct evhttp_request *req = evhttp_request_new(http_request_done, (void*)&response); // TODO RAII + if (req == NULL) + throw runtime_error("create http request failed"); + + // Get credentials + std::string strRPCUserColonPass; + if (mapArgs["-rpcpassword"] == "") { + // Try fall back to cookie-based authentication if no password is provided + if (!GetAuthCookie(&strRPCUserColonPass)) { + throw runtime_error(strprintf( + _("Could not locate RPC credentials. No authentication cookie could be found, and no rpcpassword is set in the configuration file (%s)"), + GetConfigFile().string().c_str())); - // Receive HTTP reply message headers and body - map<string, string> mapHeaders; - string strReply; - ReadHTTPMessage(stream, mapHeaders, strReply, nProto, std::numeric_limits<size_t>::max()); + } + } else { + strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; + } - if (nStatus == HTTP_UNAUTHORIZED) + struct evkeyvalq *output_headers = evhttp_request_get_output_headers(req); + assert(output_headers); + evhttp_add_header(output_headers, "Host", host.c_str()); + evhttp_add_header(output_headers, "Connection", "close"); + evhttp_add_header(output_headers, "Authorization", (std::string("Basic ") + EncodeBase64(strRPCUserColonPass)).c_str()); + + // Attach request data + std::string strRequest = JSONRPCRequest(strMethod, params, 1); + struct evbuffer * output_buffer = evhttp_request_get_output_buffer(req); + assert(output_buffer); + evbuffer_add(output_buffer, strRequest.data(), strRequest.size()); + + int r = evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/"); + if (r != 0) { + evhttp_connection_free(evcon); + event_base_free(base); + throw CConnectionFailed("send http request failed"); + } + + event_base_dispatch(base); + evhttp_connection_free(evcon); + event_base_free(base); + + if (response.status == 0) + throw CConnectionFailed("couldn't connect to server"); + else if (response.status == HTTP_UNAUTHORIZED) throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)"); - else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR) - throw runtime_error(strprintf("server returned HTTP error %d", nStatus)); - else if (strReply.empty()) + else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR) + throw runtime_error(strprintf("server returned HTTP error %d", response.status)); + else if (response.body.empty()) throw runtime_error("no response from server"); // Parse reply - Value valReply; - if (!read_string(strReply, valReply)) + UniValue valReply(UniValue::VSTR); + if (!valReply.read(response.body)) throw runtime_error("couldn't parse reply from server"); - const Object& reply = valReply.get_obj(); + const UniValue& reply = valReply.get_obj(); if (reply.empty()) throw runtime_error("expected reply to have result, error and id properties"); @@ -170,35 +235,43 @@ int CommandLineRPC(int argc, char *argv[]) // Parameters default to strings std::vector<std::string> strParams(&argv[2], &argv[argc]); - Array params = RPCConvertValues(strMethod, strParams); + UniValue params = RPCConvertValues(strMethod, strParams); // Execute and handle connection failures with -rpcwait const bool fWait = GetBoolArg("-rpcwait", false); do { try { - const Object reply = CallRPC(strMethod, params); + const UniValue reply = CallRPC(strMethod, params); // Parse reply - const Value& result = find_value(reply, "result"); - const Value& error = find_value(reply, "error"); + const UniValue& result = find_value(reply, "result"); + const UniValue& error = find_value(reply, "error"); - if (error.type() != null_type) { + if (!error.isNull()) { // Error - const int code = find_value(error.get_obj(), "code").get_int(); + int code = error["code"].get_int(); if (fWait && code == RPC_IN_WARMUP) throw CConnectionFailed("server in warmup"); - strPrint = "error: " + write_string(error, false); + strPrint = "error: " + error.write(); nRet = abs(code); + if (error.isObject()) + { + UniValue errCode = find_value(error, "code"); + UniValue errMsg = find_value(error, "message"); + strPrint = errCode.isNull() ? "" : "error code: "+errCode.getValStr()+"\n"; + + if (errMsg.isStr()) + strPrint += "error message:\n"+errMsg.get_str(); + } } else { // Result - if (result.type() == null_type) + if (result.isNull()) strPrint = ""; - else if (result.type() == str_type) + else if (result.isStr()) strPrint = result.get_str(); else - strPrint = write_string(result, true); + strPrint = result.write(2); } - // Connection succeeded, no need to retry. break; } @@ -231,6 +304,10 @@ int CommandLineRPC(int argc, char *argv[]) int main(int argc, char* argv[]) { SetupEnvironment(); + if (!SetupNetworking()) { + fprintf(stderr, "Error: Initializing networking failed\n"); + exit(1); + } try { if(!AppInitRPC(argc, argv)) diff --git a/src/bitcoin-tx-res.rc b/src/bitcoin-tx-res.rc new file mode 100644 index 0000000000..3e49b820bc --- /dev/null +++ b/src/bitcoin-tx-res.rc @@ -0,0 +1,35 @@ +#include <windows.h> // needed for VERSIONINFO +#include "clientversion.h" // holds the needed client version information + +#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD +#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD) +#define VER_FILEVERSION VER_PRODUCTVERSION +#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VER_FILEVERSION +PRODUCTVERSION VER_PRODUCTVERSION +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" // U.S. English - multilingual (hex) + BEGIN + VALUE "CompanyName", "Bitcoin" + VALUE "FileDescription", "bitcoin-tx (CLI Bitcoin transaction editor utility)" + VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "InternalName", "bitcoin-tx" + 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-tx.exe" + VALUE "ProductName", "bitcoin-tx" + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal) + END +END diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index d024b48020..5beab265bc 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -8,6 +8,7 @@ #include "consensus/consensus.h" #include "core_io.h" #include "keystore.h" +#include "policy/policy.h" #include "primitives/transaction.h" #include "script/script.h" #include "script/sign.h" @@ -69,6 +70,7 @@ static bool AppInitRawTx(int argc, char* argv[]) 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")); + strUsage += HelpMessageOpt("outdata=[VALUE:]DATA", _("Add data-based output to TX")); strUsage += HelpMessageOpt("outscript=VALUE:SCRIPT", _("Add raw script output to TX")); strUsage += HelpMessageOpt("sign=SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " + _("This command requires JSON registers:") + @@ -142,13 +144,14 @@ static void RegisterLoad(const string& strInput) valStr.insert(valStr.size(), buf, bread); } - if (ferror(f)) { + int error = ferror(f); + fclose(f); + + if (error) { string strErr = "Error reading file " + filename; throw runtime_error(strErr); } - fclose(f); - // evaluate as JSON buffer register RegisterSetJson(key, valStr); } @@ -229,6 +232,35 @@ static void MutateTxAddOutAddr(CMutableTransaction& tx, const string& strInput) tx.vout.push_back(txout); } +static void MutateTxAddOutData(CMutableTransaction& tx, const string& strInput) +{ + CAmount value = 0; + + // separate [VALUE:]DATA in string + size_t pos = strInput.find(':'); + + if (pos==0) + throw runtime_error("TX output value not specified"); + + if (pos != string::npos) { + // extract and validate VALUE + string strValue = strInput.substr(0, pos); + if (!ParseMoney(strValue, value)) + throw runtime_error("invalid TX output value"); + } + + // extract and validate DATA + string strData = strInput.substr(pos + 1, string::npos); + + if (!IsHex(strData)) + throw runtime_error("invalid TX output data"); + + std::vector<unsigned char> data = ParseHex(strData); + + CTxOut txout(value, CScript() << OP_RETURN << data); + tx.vout.push_back(txout); +} + static void MutateTxAddOutScript(CMutableTransaction& tx, const string& strInput) { // separate VALUE:SCRIPT in string @@ -346,7 +378,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) UniValue keysObj = registers["privatekeys"]; fGivenKeys = true; - for (unsigned int kidx = 0; kidx < keysObj.count(); kidx++) { + for (unsigned int kidx = 0; kidx < keysObj.size(); kidx++) { if (!keysObj[kidx].isStr()) throw runtime_error("privatekey not a string"); CBitcoinSecret vchSecret; @@ -363,7 +395,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) throw runtime_error("prevtxs register variable must be set."); UniValue prevtxsObj = registers["prevtxs"]; { - for (unsigned int previdx = 0; previdx < prevtxsObj.count(); previdx++) { + for (unsigned int previdx = 0; previdx < prevtxsObj.size(); previdx++) { UniValue prevOut = prevtxsObj[previdx]; if (!prevOut.isObject()) throw runtime_error("expected prevtxs internal object"); @@ -385,8 +417,8 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) CCoinsModifier coins = view.ModifyCoins(txid); if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) { string err("Previous output scriptPubKey mismatch:\n"); - err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+ - scriptPubKey.ToString(); + err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + "\nvs:\n"+ + ScriptToAsmStr(scriptPubKey); throw runtime_error(err); } if ((unsigned int)nOut >= coins->vout.size()) @@ -442,9 +474,18 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) tx = mergedTx; } +class Secp256k1Init +{ +public: + Secp256k1Init() { ECC_Start(); } + ~Secp256k1Init() { ECC_Stop(); } +}; + static void MutateTx(CMutableTransaction& tx, const string& command, const string& commandVal) { + boost::scoped_ptr<Secp256k1Init> ecc; + if (command == "nversion") MutateTxVersion(tx, commandVal); else if (command == "locktime") @@ -459,11 +500,15 @@ static void MutateTx(CMutableTransaction& tx, const string& command, MutateTxDelOutput(tx, commandVal); else if (command == "outaddr") MutateTxAddOutAddr(tx, commandVal); + else if (command == "outdata") + MutateTxAddOutData(tx, commandVal); else if (command == "outscript") MutateTxAddOutScript(tx, commandVal); - else if (command == "sign") + else if (command == "sign") { + if (!ecc) { ecc.reset(new Secp256k1Init()); } MutateTxSign(tx, commandVal); + } else if (command == "load") RegisterLoad(commandVal); diff --git a/src/bitcoind-res.rc b/src/bitcoind-res.rc index d183179b17..3a64acd5d1 100644 --- a/src/bitcoind-res.rc +++ b/src/bitcoind-res.rc @@ -17,13 +17,13 @@ BEGIN BLOCK "040904E4" // U.S. English - multilingual (hex) BEGIN VALUE "CompanyName", "Bitcoin" - VALUE "FileDescription", "Bitcoind (OSS daemon/client for Bitcoin)" + VALUE "FileDescription", "bitcoind (Bitcoin node with a JSON-RPC server)" VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoind" 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", "bitcoind.exe" - VALUE "ProductName", "Bitcoind" + VALUE "ProductName", "bitcoind" VALUE "ProductVersion", VER_PRODUCTVERSION_STR END END diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index eeca8655c9..b512f74c22 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -3,17 +3,23 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "chainparams.h" #include "clientversion.h" #include "rpcserver.h" #include "init.h" -#include "main.h" #include "noui.h" +#include "scheduler.h" #include "util.h" +#include "httpserver.h" +#include "httprpc.h" +#include "rpcserver.h" #include <boost/algorithm/string/predicate.hpp> #include <boost/filesystem.hpp> #include <boost/thread.hpp> +#include <stdio.h> + /* Introduction text for doxygen: */ /*! \mainpage Developer documentation @@ -43,7 +49,7 @@ void WaitForShutdown(boost::thread_group* threadGroup) } if (threadGroup) { - threadGroup->interrupt_all(); + Interrupt(*threadGroup); threadGroup->join_all(); } } @@ -55,6 +61,7 @@ void WaitForShutdown(boost::thread_group* threadGroup) bool AppInit(int argc, char* argv[]) { boost::thread_group threadGroup; + CScheduler scheduler; bool fRet = false; @@ -142,7 +149,7 @@ bool AppInit(int argc, char* argv[]) #endif SoftSetBoolArg("-server", true); - fRet = AppInit2(threadGroup); + fRet = AppInit2(threadGroup, scheduler); } catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInit()"); @@ -152,7 +159,7 @@ bool AppInit(int argc, char* argv[]) if (!fRet) { - threadGroup.interrupt_all(); + Interrupt(threadGroup); // threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of // the startup-failure cases to make sure they don't result in a hang due to some // thread-blocking-waiting-for-another-thread-during-startup case diff --git a/src/bloom.cpp b/src/bloom.cpp index 36cba491c4..de87206592 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -8,6 +8,7 @@ #include "hash.h" #include "script/script.h" #include "script/standard.h" +#include "random.h" #include "streams.h" #include <math.h> @@ -121,6 +122,12 @@ void CBloomFilter::clear() isEmpty = true; } +void CBloomFilter::reset(unsigned int nNewTweak) +{ + clear(); + nTweak = nNewTweak; +} + bool CBloomFilter::IsWithinSizeConstraints() const { return vData.size() <= MAX_BLOOM_FILTER_SIZE && nHashFuncs <= MAX_HASH_FUNCS; @@ -209,15 +216,17 @@ void CBloomFilter::UpdateEmptyFull() isEmpty = empty; } -CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate, unsigned int nTweak) : - b1(nElements * 2, fpRate, nTweak), b2(nElements * 2, fpRate, nTweak) +CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate) : + b1(nElements * 2, fpRate, 0), b2(nElements * 2, fpRate, 0) { // 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. - nBloomSize = nElements * 2; nInsertions = 0; + nBloomSize = nElements * 2; + + reset(); } void CRollingBloomFilter::insert(const std::vector<unsigned char>& vKey) @@ -234,6 +243,12 @@ void CRollingBloomFilter::insert(const std::vector<unsigned char>& vKey) } } +void CRollingBloomFilter::insert(const uint256& hash) +{ + vector<unsigned char> data(hash.begin(), hash.end()); + insert(data); +} + bool CRollingBloomFilter::contains(const std::vector<unsigned char>& vKey) const { if (nInsertions < nBloomSize / 2) { @@ -242,9 +257,16 @@ bool CRollingBloomFilter::contains(const std::vector<unsigned char>& vKey) const return b1.contains(vKey); } -void CRollingBloomFilter::clear() +bool CRollingBloomFilter::contains(const uint256& hash) const +{ + vector<unsigned char> data(hash.begin(), hash.end()); + return contains(data); +} + +void CRollingBloomFilter::reset() { - b1.clear(); - b2.clear(); + unsigned int nNewTweak = GetRand(std::numeric_limits<unsigned int>::max()); + b1.reset(nNewTweak); + b2.reset(nNewTweak); nInsertions = 0; } diff --git a/src/bloom.h b/src/bloom.h index 7bab379a39..a4dba8cb4f 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -32,14 +32,14 @@ enum bloomflags /** * BloomFilter is a probabilistic filter which SPV clients provide - * so that we can filter the transactions we sends them. + * so that we can filter the transactions we send them. * * This allows for significantly more efficient transaction and block downloads. * - * Because bloom filters are probabilistic, an SPV node can increase the false- - * positive rate, making us send them transactions which aren't actually theirs, + * Because bloom filters are probabilistic, a SPV node can increase the false- + * positive rate, making us send it transactions which aren't actually its, * allowing clients to trade more bandwidth for more privacy by obfuscating which - * keys are owned by them. + * keys are controlled by them. */ class CBloomFilter { @@ -89,6 +89,7 @@ public: bool contains(const uint256& hash) const; void clear(); + void reset(unsigned int nNewTweak); //! True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS //! (catch a filter which was just deserialized which was too big) @@ -103,7 +104,11 @@ public: /** * RollingBloomFilter is a probabilistic "keep track of most recently inserted" set. - * Construct it with the number of items to keep track of, and a false-positive rate. + * Construct it with the number of items to keep track of, and a false-positive + * rate. Unlike CBloomFilter, by default nTweak is set to a cryptographically + * secure random value for you. Similarly rather than clear() the method + * 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 * insert()'ed ... but may also return true for items that were not inserted. @@ -111,12 +116,17 @@ public: class CRollingBloomFilter { public: - CRollingBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweak); + // A random bloom filter calls GetRand() at creation time. + // Don't create global CRollingBloomFilter objects, as they may be + // constructed before the randomizer is properly initialized. + CRollingBloomFilter(unsigned int nElements, double nFPRate); void insert(const std::vector<unsigned char>& vKey); + void insert(const uint256& hash); bool contains(const std::vector<unsigned char>& vKey) const; + bool contains(const uint256& hash) const; - void clear(); + void reset(); private: unsigned int nBloomSize; diff --git a/src/chain.cpp b/src/chain.cpp index 719256106e..5b8ce076c4 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -82,9 +82,10 @@ CBlockIndex* CBlockIndex::GetAncestor(int height) while (heightWalk > height) { int heightSkip = GetSkipHeight(heightWalk); int heightSkipPrev = GetSkipHeight(heightWalk - 1); - if (heightSkip == height || - (heightSkip > height && !(heightSkipPrev < heightSkip - 2 && - heightSkipPrev >= height))) { + if (pindexWalk->pskip != NULL && + (heightSkip == height || + (heightSkip > height && !(heightSkipPrev < heightSkip - 2 && + heightSkipPrev >= height)))) { // Only follow pskip if pprev->pskip isn't better than pskip->pprev. pindexWalk = pindexWalk->pskip; heightWalk = heightSkip; diff --git a/src/chain.h b/src/chain.h index 02f53cd2f2..01be2d6e5c 100644 --- a/src/chain.h +++ b/src/chain.h @@ -74,7 +74,7 @@ enum BlockStatus { */ BLOCK_VALID_TRANSACTIONS = 3, - //! Outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends, BIP30. + //! Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends, BIP30. //! Implies all parents are also at least CHAIN. BLOCK_VALID_CHAIN = 4, diff --git a/src/chainparams.cpp b/src/chainparams.cpp index a3434bd6e8..15b86cdda6 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -12,10 +12,47 @@ #include <boost/assign/list_of.hpp> -using namespace std; - #include "chainparamsseeds.h" +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; + txNew.nVersion = 1; + txNew.vin.resize(1); + txNew.vout.resize(1); + txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vout[0].nValue = genesisReward; + txNew.vout[0].scriptPubKey = genesisOutputScript; + + CBlock genesis; + genesis.nTime = nTime; + genesis.nBits = nBits; + genesis.nNonce = nNonce; + genesis.nVersion = nVersion; + genesis.vtx.push_back(txNew); + genesis.hashPrevBlock.SetNull(); + genesis.hashMerkleRoot = genesis.ComputeMerkleRoot(); + return genesis; +} + +/** + * Build the genesis block. Note that the output of its generation + * transaction cannot be spent since it did not originally exist in the + * database. + * + * CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1) + * CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) + * CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73) + * CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) + * vMerkleTree: 4a5e1e + */ +static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) +{ + const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; + const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; + return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); +} + /** * Main network */ @@ -26,51 +63,6 @@ using namespace std; * timestamp before) * + Contains no strange transactions */ -static Checkpoints::MapCheckpoints mapCheckpoints = - boost::assign::map_list_of - ( 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) - ( 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) - ( 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) - (105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")) - (134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")) - (168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")) - (193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")) - (210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")) - (216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")) - (225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")) - (250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")) - (279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")) - (295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")) - ; -static const Checkpoints::CCheckpointData data = { - &mapCheckpoints, - 1397080064, // * UNIX timestamp of last checkpoint block - 36544669, // * total number of transactions between genesis and last checkpoint - // (the tx=... number in the SetBestChain debug.log lines) - 60000.0 // * estimated number of transactions per day after checkpoint - }; - -static Checkpoints::MapCheckpoints mapCheckpointsTestnet = - boost::assign::map_list_of - ( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")) - ; -static const Checkpoints::CCheckpointData dataTestnet = { - &mapCheckpointsTestnet, - 1337966069, - 1488, - 300 - }; - -static Checkpoints::MapCheckpoints mapCheckpointsRegtest = - boost::assign::map_list_of - ( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")) - ; -static const Checkpoints::CCheckpointData dataRegtest = { - &mapCheckpointsRegtest, - 0, - 0, - 0 - }; class CMainParams : public CChainParams { public: @@ -87,7 +79,7 @@ public: /** * 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 4-byte int at any alignment. + * a large 32-bit integer with any alignment. */ pchMessageStart[0] = 0xf9; pchMessageStart[1] = 0xbe; @@ -95,34 +87,9 @@ public: pchMessageStart[3] = 0xd9; vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); nDefaultPort = 8333; - nMinerThreads = 0; nPruneAfterHeight = 100000; - /** - * Build the genesis block. Note that the output of the genesis coinbase cannot - * be spent as it did not originally exist in the database. - * - * CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1) - * CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) - * CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73) - * CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) - * vMerkleTree: 4a5e1e - */ - const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; - CMutableTransaction txNew; - txNew.vin.resize(1); - txNew.vout.resize(1); - txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); - txNew.vout[0].nValue = 50 * COIN; - txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; - genesis.vtx.push_back(txNew); - genesis.hashPrevBlock.SetNull(); - genesis.hashMerkleRoot = genesis.BuildMerkleTree(); - genesis.nVersion = 1; - genesis.nTime = 1231006505; - genesis.nBits = 0x1d00ffff; - genesis.nNonce = 2083236893; - + genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); @@ -130,8 +97,9 @@ public: vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be")); // 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")); // Addy Yeow + 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 base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0); base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5); @@ -141,17 +109,32 @@ public: vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main)); - fRequireRPCPassword = true; fMiningRequiresPeers = true; fDefaultConsistencyChecks = false; fRequireStandard = true; fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = false; - } - const Checkpoints::CCheckpointData& Checkpoints() const - { - return data; + checkpointData = (CCheckpointData) { + boost::assign::map_list_of + ( 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) + ( 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) + ( 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) + (105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")) + (134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")) + (168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")) + (193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")) + (210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")) + (216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")) + (225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")) + (250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")) + (279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")) + (295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")), + 1397080064, // * UNIX timestamp of last checkpoint block + 36544669, // * total number of transactions between genesis and last checkpoint + // (the tx=... number in the SetBestChain debug.log lines) + 60000.0 // * estimated number of transactions per day after checkpoint + }; } }; static CMainParams mainParams; @@ -159,13 +142,17 @@ static CMainParams mainParams; /** * Testnet (v3) */ -class CTestNetParams : public CMainParams { +class CTestNetParams : public CChainParams { public: CTestNetParams() { strNetworkID = "test"; + consensus.nSubsidyHalvingInterval = 210000; consensus.nMajorityEnforceBlockUpgrade = 51; consensus.nMajorityRejectBlockOutdated = 75; consensus.nMajorityWindow = 100; + consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks + consensus.nPowTargetSpacing = 10 * 60; consensus.fPowAllowMinDifficultyBlocks = true; pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; @@ -173,14 +160,12 @@ public: pchMessageStart[3] = 0x07; vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"); nDefaultPort = 18333; - nMinerThreads = 0; nPruneAfterHeight = 1000; - //! Modify the testnet genesis block so the timestamp is valid for a later start. - genesis.nTime = 1296688602; - genesis.nNonce = 414098458; + genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943")); + assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); vFixedSeeds.clear(); vSeeds.clear(); @@ -197,16 +182,20 @@ public: vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test)); - fRequireRPCPassword = true; fMiningRequiresPeers = true; fDefaultConsistencyChecks = false; fRequireStandard = false; fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = true; - } - const Checkpoints::CCheckpointData& Checkpoints() const - { - return dataTestnet; + + checkpointData = (CCheckpointData) { + boost::assign::map_list_of + ( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")), + 1337966069, + 1488, + 300 + }; + } }; static CTestNetParams testNetParams; @@ -214,7 +203,7 @@ static CTestNetParams testNetParams; /** * Regression test */ -class CRegTestParams : public CTestNetParams { +class CRegTestParams : public CChainParams { public: CRegTestParams() { strNetworkID = "regtest"; @@ -223,32 +212,43 @@ public: consensus.nMajorityRejectBlockOutdated = 950; consensus.nMajorityWindow = 1000; consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks + consensus.nPowTargetSpacing = 10 * 60; + consensus.fPowAllowMinDifficultyBlocks = true; + pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; pchMessageStart[2] = 0xb5; pchMessageStart[3] = 0xda; - nMinerThreads = 1; - genesis.nTime = 1296688602; - genesis.nBits = 0x207fffff; - genesis.nNonce = 2; - consensus.hashGenesisBlock = genesis.GetHash(); nDefaultPort = 18444; - assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); nPruneAfterHeight = 1000; + genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN); + consensus.hashGenesisBlock = genesis.GetHash(); + 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. - fRequireRPCPassword = false; fMiningRequiresPeers = false; fDefaultConsistencyChecks = true; fRequireStandard = false; fMineBlocksOnDemand = true; fTestnetToBeDeprecatedFieldRPC = false; - } - const Checkpoints::CCheckpointData& Checkpoints() const - { - return dataRegtest; + + checkpointData = (CCheckpointData){ + boost::assign::map_list_of + ( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")), + 0, + 0, + 0 + }; + base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111); + base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196); + base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239); + base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >(); + base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >(); } }; static CRegTestParams regTestParams; diff --git a/src/chainparams.h b/src/chainparams.h index bf76eb110a..5db39aa09c 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -7,7 +7,6 @@ #define BITCOIN_CHAINPARAMS_H #include "chainparamsbase.h" -#include "checkpoints.h" #include "consensus/params.h" #include "primitives/block.h" #include "protocol.h" @@ -24,6 +23,14 @@ struct SeedSpec6 { uint16_t port; }; +typedef std::map<int, uint256> MapCheckpoints; + +struct CCheckpointData { + MapCheckpoints mapCheckpoints; + int64_t nTimeLastCheckpoint; + int64_t nTransactionsLastCheckpoint; + double fTransactionsPerDay; +}; /** * CChainParams defines various tweakable parameters of a given instance of the @@ -49,20 +56,13 @@ public: const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; } int GetDefaultPort() const { return nDefaultPort; } - int SubsidyHalvingInterval() const { return consensus.nSubsidyHalvingInterval; } - int EnforceBlockUpgradeMajority() const { return consensus.nMajorityEnforceBlockUpgrade; } - int RejectBlockOutdatedMajority() const { return consensus.nMajorityRejectBlockOutdated; } - int ToCheckBlockUpgradeMajority() const { return consensus.nMajorityWindow; } - /** Used if GenerateBitcoins is called with a negative number of threads */ - int DefaultMinerThreads() const { return nMinerThreads; } const CBlock& GenesisBlock() const { return genesis; } - bool RequireRPCPassword() const { return fRequireRPCPassword; } /** Make miner wait to have peers to avoid wasting work */ bool MiningRequiresPeers() const { return fMiningRequiresPeers; } /** Default value for -checkmempool and -checkblockindex argument */ bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; } - /** Make standard checks */ + /** Policy: Filter transactions that do not match well-defined patterns */ bool RequireStandard() const { return fRequireStandard; } int64_t PruneAfterHeight() const { return nPruneAfterHeight; } /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ @@ -74,7 +74,7 @@ public: const std::vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; } const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; } - virtual const Checkpoints::CCheckpointData& Checkpoints() const = 0; + const CCheckpointData& Checkpoints() const { return checkpointData; } protected: CChainParams() {} @@ -83,24 +83,23 @@ protected: //! Raw pub key bytes for the broadcast alert signing key. std::vector<unsigned char> vAlertPubKey; int nDefaultPort; - int nMinerThreads; uint64_t nPruneAfterHeight; std::vector<CDNSSeedData> vSeeds; std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES]; std::string strNetworkID; CBlock genesis; std::vector<SeedSpec6> vFixedSeeds; - bool fRequireRPCPassword; bool fMiningRequiresPeers; bool fDefaultConsistencyChecks; bool fRequireStandard; bool fMineBlocksOnDemand; bool fTestnetToBeDeprecatedFieldRPC; + CCheckpointData checkpointData; }; /** - * Return the currently selected parameters. This won't change after app startup - * outside of the unit tests. + * Return the currently selected parameters. This won't change after app + * startup, except for unit tests. */ const CChainParams &Params(); diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index 7d82d689ec..9c87bf2154 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -25,7 +25,7 @@ static CBaseMainParams mainParams; /** * Testnet (v3) */ -class CBaseTestNetParams : public CBaseMainParams +class CBaseTestNetParams : public CBaseChainParams { public: CBaseTestNetParams() @@ -39,11 +39,12 @@ static CBaseTestNetParams testNetParams; /* * Regression test */ -class CBaseRegTestParams : public CBaseTestNetParams +class CBaseRegTestParams : public CBaseChainParams { public: CBaseRegTestParams() { + nRPCPort = 18332; strDataDir = "regtest"; } }; diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index 421a3a06ff..4369d0aef7 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -34,8 +34,8 @@ protected: }; /** - * Return the currently selected parameters. This won't change after app startup - * outside of the unit tests. + * Return the currently selected parameters. This won't change after app + * startup, except for unit tests. */ const CBaseChainParams& BaseParams(); diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index 6b6e5103f5..423362859f 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -2,551 +2,900 @@ #define BITCOIN_CHAINPARAMSSEEDS_H /** * List of fixed seed nodes for the bitcoin network - * AUTOGENERATED by share/seeds/generate-seeds.py + * AUTOGENERATED by contrib/seeds/generate-seeds.py * * Each line contains a 16-byte IPv6 address and a port. * 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,0x21,0xc5,0x6e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0x22,0xb4,0xf5}, 8333}, + {{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,0x23,0xc3,0x19}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x64,0x7b,0x13}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xaf,0x91,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0x85,0xc1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0x97,0x0a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xe4,0x01,0xe6}, 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,0x1e,0xf3,0x99}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x58,0xe8,0x31}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x63,0x69,0x09}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe2,0x89,0xd0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe3,0xb1,0xa1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe3,0xbf,0x32}, 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,0x17,0xec,0x90,0x45}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xfd,0x94,0x71}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xfd,0xf1,0x16}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xff,0xe3,0xe7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x14,0xcd,0xde}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x17,0x78,0xfc}, 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,0x62,0x5f,0xc9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x6f,0x5a,0x37}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x77,0x77,0x69}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x8a,0x19,0x95}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x03,0xd6,0x2d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xba,0x57,0x2e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xba,0x65,0x62}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xba,0xfa,0xba}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xcc,0x99,0x6b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x2c,0x10,0xe7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x2c,0x2c,0x0b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x78,0xa8,0xcc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x8f,0x56,0x1a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x4b,0x18}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbc,0x44,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc0,0x5f,0x96}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc9,0xf6,0x74}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xcd,0x0a,0x8c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x0a,0xd2,0x11}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x13,0x8a,0x9a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcc,0x7b}, 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,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,0x2e,0xa6,0xa2,0x5b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xad,0xbe,0x32}, 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,0xe3,0x42,0x84}, 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,0xec,0x74,0xd1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x37,0x0e,0x41}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x07,0xfc,0xe5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x2e,0x9f,0x5b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4e,0x31,0xb5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4e,0xe7,0x39}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4f,0x99,0x41}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x22,0x2c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x7e,0x56,0xfd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x8e,0x29,0x17}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xc7,0x71,0xc1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xc8,0x4e,0x6b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xce,0x8a,0xb1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xfc,0x34,0x31}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa5,0x19,0x4b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa9,0x6b,0x28}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xb3,0xbe,0x38}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xbb,0x52,0x79}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf6,0x55,0xf6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x4a,0x07,0xcd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x60,0xb7,0x79}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x3e,0x3a,0x26}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x3f,0x5b,0x48}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x3f,0x5b,0x70}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x48,0xd3,0xe4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x2b,0x28,0x9a}, 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,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,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,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,0x50,0xb9,0xd5}, 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,0xad,0x8b,0x3a}, 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,0xd2,0x72,0x7f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0x8d,0xe4,0x8a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0x99,0xd5,0x4e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0xdf,0x54,0x91}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0xfb,0x58,0x70}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x1f,0x6e,0x32}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x22,0x79,0x2d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x72,0x06,0x2a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x8c,0x7d,0x62}, 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,0x41,0x1e,0x2f,0x74}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x23,0x84,0xb1}, 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,0x41,0x6f,0xbd,0x1a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x44,0x0a,0x1e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x72,0x21,0xfa}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x82,0x2e,0x3f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xaf,0xd7,0x87}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xbe,0xfd,0xa5}, 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,0xf4,0x62,0x6f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa2,0xee,0x1e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa9,0xff,0x11}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xb7,0xad,0x19}, 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,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,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,0x43,0xe3,0xf0,0x73}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xf7,0xde,0x47}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x2b,0x72,0x42}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x34,0x21,0x24}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xc6,0xf5,0xf1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x0c,0xe2,0xa5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x0d,0xc6,0xbc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x0f,0xb3,0x3e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x27,0xef,0x2f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x2f,0x2d,0x57}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x3e,0xd9,0xce}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x2a,0x1f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x51,0x3d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x43,0xdb,0xc8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x5a,0x84,0x9d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x5e,0x1e,0xb1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x88,0xaf,0xf1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x3d,0x61,0xe4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x7b,0x76,0x84}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x3b,0x98,0xb6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc6,0xf8,0x97}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc8,0xf2,0x59}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xe1,0xb3,0x9d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x0e,0xbb,0x33}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x26,0x22,0xb4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x34,0x48,0xbb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x5b,0x90,0xb6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xa7,0x31,0xd9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xc9,0xf3,0x37}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xdf,0x3c,0xf9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xe4,0x99,0x66}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x1a,0x65,0xe4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x32,0x9e,0xc8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xb5,0xcc,0xaa}, 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,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,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,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,0x3f,0xde,0xe2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x51,0xe7,0x15}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xc1,0x7e,0x52}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xcf,0xeb,0xa4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x53,0xc5,0x72}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x90,0x72,0x09}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x70,0x05,0xf7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0xae,0x14,0xf7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x25,0xf0,0x8e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x39,0xca,0x6b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xac,0x7b,0x35}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xdd,0x5b,0xfd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xeb,0x30,0x30}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xf5,0x4e,0x02}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x08,0x3a,0xf9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x1b,0xbf,0xb6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x81,0xec,0x8d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x83,0x58,0x2f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x9d,0xcd,0x06}, 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,0x4e,0x54,0x64,0x5f}, 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,0x8f,0xbc,0x9b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa0,0xdd,0x8c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa1,0x6f,0x72}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x64,0xbd,0x03}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x93,0x8c,0x79}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xcb,0x4b,0x85}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xdc,0x63,0xe3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xde,0x14,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xf1,0x01,0x07}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x17,0xbf,0xf3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x26,0x0b,0xca}, 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,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,0x6e,0xd5,0xa5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x85,0x9b,0xed}, 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,0xb5,0x9b,0xb4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x27,0x9c,0x89}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x49,0xa1,0x5f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x82,0x2d,0x28}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xa5,0x99,0x2f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xa8,0x80,0x85}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xb3,0xe1,0x76}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc2,0xf5,0x9e}, 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,0x52,0xc7,0x66,0x0a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xd3,0x1e,0xf3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xd9,0x85,0x91}, 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,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,0xdd,0x83,0xb1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xe9,0xe1,0xcd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x00,0xf9,0x92}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x59,0x1f,0xf9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x80,0x1d,0xe7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x80,0xfd,0x8e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x8f,0x82,0x38}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x96,0x02,0x63}, 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,0x53,0x96,0x09,0xc4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xa1,0x40,0x2d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xd4,0x67,0xd4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xd4,0x6f,0x72}, 8333}, - {{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,0xfe,0x51,0x1f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xfe,0x96,0x36}, 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,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,0x0f,0x3d,0x3c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x11,0x19,0x87}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x2a,0x90,0x13}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd4,0xd2,0x87}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd7,0xa5,0xe7}, 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,0xf0,0x1f,0xb8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0xd6,0x89}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x8b,0xa3,0x84}, 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,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,0x3d,0xd1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x6c,0x4d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x7b,0x10,0x11}, 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,0xe5,0x49,0xab}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xec,0xc4,0x4d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x61,0x38,0x62}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x86,0xb2,0x59}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x96,0xe9,0x13}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xa8,0x85,0x03}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x12,0xf6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x21,0xca}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x12,0x1c,0x15}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x55,0xdc,0x54}, 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,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,0xb8,0x53,0x3c}, 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,0xec,0x31,0x75}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x5a,0x42,0xd1}, 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,0x5b,0x86,0x4b,0x73}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x98,0xc1,0x24}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x98,0xdb,0x23}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xc5,0x0a,0xea}, 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,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,0x6a,0x93}, 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,0xdf,0x73,0x26}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xea,0x30,0xe8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xfa,0x56,0x12}, 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,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,0x54,0x72,0x6a}, 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,0xab,0xd8,0xdd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xb9,0xb1,0x47}, 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,0x5e,0x2a,0x73,0x32}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x4f,0xb1,0xce}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x88,0x93,0x77}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x8f,0xf5,0x05}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xbc,0x32,0x27}, 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,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,0xdb,0x5a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf2,0xe5,0xa8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf4,0xa0,0x54}, 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,0x55,0x19,0x29}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x69,0xa1,0x88}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x9a,0xa5,0x2d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x9a,0xc8,0xd8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xa7,0x6d,0x7d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0x7d,0xe7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0xd8,0xeb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x21,0x19,0x11}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x2b,0x82,0xb2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x76,0x08,0xec}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x66,0x06,0x7d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xca,0x14,0x2d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xd9,0x7d,0xe1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xea,0xd2,0x6f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xed,0x14,0x7b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xff,0x90,0xb0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0x71,0x40,0x2b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0xe5,0x16,0x08}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x01,0xd4,0x13}, 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,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,0x67,0xe0,0xa5,0x30}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xf3,0x5e,0x8c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x83,0x6b,0x6b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x83,0x74,0xb8}, 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,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,0xdb,0xb8,0x09}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xb9,0x26,0xae}, 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,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,0x6b,0x06,0x04,0x91}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x08,0x1b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x21,0x14}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xaa,0xe4,0x81}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xaa,0xf0,0xad}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x33,0x14,0x56}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x95,0xde}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x97,0xac}, 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,0x6c,0xaa,0x8c,0x15}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x3c,0xd3,0xd8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x49,0x2a,0x24}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x49,0xac,0x8a}, 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,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,0xc9,0x87,0xd8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe4,0x98,0x02}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe4,0x9a,0x51}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe6,0xdc,0x7d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xea,0x9c,0xda}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xeb,0x31,0x1b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xeb,0x45,0x54}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x70,0x7c,0x47,0x00}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x92,0x44,0xfb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x1d,0x11,0x52}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x46,0xb0,0x11}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x75,0x29,0xa2,0xb8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x1b,0x08,0xaa}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xe6,0x07,0xd3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xf6,0x47,0x34}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0xac,0x08,0x64}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7a,0x80,0x6d,0x94}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xe7,0xe0,0x3f}, 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,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,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,0xa4,0x60}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0xfe,0xf4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x61,0x45,0x4c}, 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,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,0x81,0x7b,0x07,0x27}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0xba,0x11,0x11}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0xf7,0xa9,0xbe}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x85,0xf2,0xd1,0x3f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0x66,0x5e,0x26}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0x77,0x11,0x91}, 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,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,0x8a,0xd2,0xd9,0xaa}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0xff,0xa6,0xc2}, 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,0x90,0x4c,0xf4,0x13}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0x94,0x34,0xa2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0x94,0x50,0x39}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0x13,0x1e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0x8e,0x56}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0xfd,0x33}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x94,0xfb,0x06,0xd6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0x9a,0x9b,0xeb}, 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,0x97,0xe0,0xf8,0xfc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x79,0x4b,0xe5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x7f,0xfb,0x43}, 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,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,0x9d,0x0d,0x3d,0x05}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9e,0x3a,0xad,0x30}, 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,0xa2,0xd1,0x6e,0xda}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd5,0xfe,0xcd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xef,0xfe,0x64}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf2,0x96,0x27}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x51,0x8a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0xeb,0x38}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf4,0x4f,0x10}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf5,0xd9,0x77}, 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,0xa2,0xfb,0x6c,0x35}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xfe,0x95,0x8b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xff,0x74,0x4e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0x46,0x5e,0x6a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0x58,0x2d,0x7c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0x58,0x78,0xd2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x1a,0x31,0x2b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x1e,0x0e,0x06}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x50,0x72,0xc5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xa7,0xd6,0xf3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xd0,0xdb,0x6c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xdc,0x43,0x9c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xec,0x65,0x22}, 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,0xff,0xed,0xf1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x02,0xd5,0xd1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x33,0x17,0xe0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x33,0x7b,0x9f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x39,0xd4,0x79}, 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,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,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,0xaf,0x7e,0x7c,0x5b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaf,0x7e,0x7c,0x5c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x0a,0x74,0xf2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x23,0x7e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x63,0xde}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x7c,0x6e,0x2f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xc2,0x21,0x2c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xdf,0xc9,0xc6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x1a,0x53}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x24,0x30}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0xd4,0x8d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0xfe,0x3b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4e,0xfa,0x03}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x9b,0x56,0xe2}, 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,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,0xfe,0x22,0xa1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb3,0x2b,0x72,0x0e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb6,0xd5,0xd0,0x1c}, 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,0x48,0xee,0x2a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x5e,0xe2,0x22}, 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,0x6b,0x8b,0x3a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x6b,0xce,0x2d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x0a,0x30,0x75}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x15,0xd8,0x9c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x26,0x2f,0xe0}, 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,0x35,0x81,0xe6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x35,0x83,0x72}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x37,0x35,0x3d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x37,0x35,0x3f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x3d,0x77,0x02}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x3d,0x94,0xcb}, 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,0xbc,0x5c,0x4b,0xb2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x7a,0x5c,0x86}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x09,0xd0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa5,0xd1,0x94}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xe2,0xce,0xef}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x08,0x7c}, 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,0xc0,0x00,0x82,0x8e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x03,0x59,0x9f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x49,0xea,0x8a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x4b,0x5f,0x6b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x5f,0x64,0x66}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x9b,0x54,0xb5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xa9,0xe9,0xce}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xc6,0x5d,0x56}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xe3,0x87,0xd8}, 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,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,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,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,0xc1,0x00,0x6d,0x03}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x4d,0x32,0xd0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x6d,0x44,0x3e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x96,0x79,0x25}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xe0,0x45,0x62}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x4f,0x08,0x25}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x8d,0x56,0x0a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x0c,0xb4,0x5e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x38,0x3f,0x0a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x74,0x5d,0x5d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9a,0xae,0xe2}, 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,0xa9,0x8a,0x02}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xbd,0x7e,0x23}, 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,0xc3,0xc5,0xaf,0xbe}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc5,0xf2,0x5d,0x52}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x0b,0xd6,0x93}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x31,0x29,0x15}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x21,0x7c,0xba}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xcc,0xba,0x92}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xe9,0xee,0x73}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xf1,0xbd,0x42}, 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,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,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,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,0xcb,0xb7,0x97,0x27}, 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,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,0xcc,0x2c,0x7b,0x6d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x2c,0x7b,0xa2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x2d,0x78,0xb2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xbe,0x86,0x2c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xf8,0xb8,0x7f}, 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,0x42,0x1e,0x1b}, 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,0x69,0xf3,0xe5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x7e,0x46,0x9f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x8c,0x1e,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xa5,0x80,0xeb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xbe,0x02,0xf2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0x42,0xfe,0xec}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0x49,0x1b,0x21}, 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,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,0xd4,0x19,0x25,0x7c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x47,0xeb,0x72}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x47,0xfc,0x6d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x72,0x30,0x1f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0xae,0x97,0x76}, 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,0x7e,0x0e,0x7a}, 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,0x81,0xf8,0x8b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x88,0x57,0x22}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa5,0x52,0x85}, 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,0xb3,0x9e,0xfd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xbd,0x35,0x7d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xde,0xd0,0x5d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x31,0x9e,0xa1}, 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,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,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,0x83,0x5b,0x64}, 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,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,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,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,0x17,0x06,0x85}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x4b,0x58,0xb2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xac,0x8f,0x8c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xc3,0xa9,0xd1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xc4,0xf8,0x6a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdb,0x8a,0xa1,0xa2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xde,0xa7,0xf8,0x5a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0x12,0xfe,0x37}, 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,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}, + {{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,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,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,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,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,0x9c,0x94,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,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,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,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,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,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,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,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,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,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,0x48,0x00,0x78,0x19,0x01,0x04,0xbe,0x76,0x4e,0xff,0xfe,0x05,0xc8,0x28}, 8333}, + {{0x20,0x01,0x48,0x02,0x78,0x00,0x00,0x02,0x30,0xd7,0x17,0x75,0xff,0x20,0x18,0x58}, 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,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,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,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,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,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,0xb0,0x09,0x20,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x09,0x20,0xc5}, 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}, + {{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,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,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,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,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,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,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,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,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,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,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,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,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,0xf1,0xc0,0x08,0x48,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x94,0x3c}, 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}, + {{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,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,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,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,0x44,0xe7,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,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,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,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,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,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,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,0x51,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 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,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,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,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,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,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,0x53,0xc3,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,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,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,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,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,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,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,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,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,0x0f,0x80,0xed,0x16,0x0c,0xa7,0xea,0x75,0xb1,0x2d,0x02,0xaf,0x9e,0x2a}, 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,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,0x0a,0x26,0x27,0x21,0xae,0x94,0xd5,0xc2,0x72,0x24}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xea,0xb9,0x5b,0x63,0x1d,0x94,0xe2,0xed,0xec,0xa1}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xce,0x36,0xa1,0xc1,0xd6,0x64,0x43,0xfb,0xb3,0xe7}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x26,0xe6,0xdf,0xeb,0xe5,0xc5,0x9a,0x87,0x5e,0x22}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x52,0x71,0xa2,0x43,0x2a,0xe6,0x6c,0x8e,0xe4,0x7b}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7c,0xf4,0x0b,0x4c,0x52,0xd5,0x16,0xcf,0xf5,0x06}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x98,0xff,0x33,0x38,0xbb,0x43,0x08,0x8d,0x95,0x9e}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x16,0x64,0x1b,0x1f,0x8f,0x87,0x18,0x7d,0xa3,0x2b}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb8,0xda,0x83,0x67,0x90,0x6f,0x46,0x10,0xdb,0x53}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc3,0x1b,0x22,0x8c,0x89,0x60,0xbf,0xca,0x88,0xa1}, 7033}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4d,0xe3,0x5b,0x75,0x10,0x46,0x5e,0xf0,0x99,0x8b}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0xba,0x44,0x94,0x9d,0xf5,0xc0,0xaa,0xcd,0x4a}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x96,0x64,0xce,0x6d,0xd4,0xfb,0xa7,0x6b,0x60,0xb5}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe9,0x8f,0x0b,0x72,0xc9,0xf1,0xde,0x62,0xd4,0x66}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x25,0x5c,0xbc,0x34,0xe8,0x9f,0xe4,0x7c,0x90,0x93}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe0,0xa2,0x72,0xef,0xfa,0x7b,0x88,0x95,0x8b,0x9c}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x99,0x69,0xc5,0x40,0xa7,0x95,0xbb,0x25,0xc1,0xfa}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x46,0xa3,0xd9,0x84,0x08,0xc8,0x7f,0xd3,0xeb,0xc5}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0c,0xc4,0xd2,0x4f,0x74,0x99,0xb3,0x8c,0xe8,0x25}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xac,0x9d,0xb8,0xf8,0x4c,0x4b,0x9c,0xc3,0x9c,0xc6}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7c,0x1d,0x28,0x9f,0xd6,0x28,0x28,0x22,0x4f,0x7a}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xce,0x36,0xa1,0xc1,0xd6,0x64,0x43,0xfb,0xb3,0xe7}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8f,0x06,0x4e,0x64,0xbc,0x5e,0x1a,0x8a,0x71,0x97}, 8444} + {{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,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,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,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} }; static SeedSpec6 pnSeed6_test[] = { {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x99,0xcb,0x26,0x31,0xba,0x48,0x51,0x31,0x39,0x0d}, 18333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x44,0xf4,0xf4,0xf0,0xbf,0xf7,0x7e,0x6d,0xc4,0xe8}, 18333} + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x44,0xf4,0xf4,0xf0,0xbf,0xf7,0x7e,0x6d,0xc4,0xe8}, 18333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6a,0x8b,0xd2,0x78,0x3f,0x7a,0xf8,0x92,0x8f,0x80}, 18333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe6,0x4e,0xa4,0x47,0x4e,0x2a,0xfe,0xe8,0x95,0xcc}, 18333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9f,0xae,0x9f,0x59,0x0b,0x3f,0x31,0x3a,0x8a,0x5f}, 18333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x47,0xb1,0xe4,0x55,0xd1,0xb0,0x14,0x3f,0xb6,0xdb}, 18333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa0,0x60,0x9e,0x46,0x54,0xdb,0x61,0x3b,0xb2,0x6f}, 18333} }; #endif // BITCOIN_CHAINPARAMSSEEDS_H diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 71579bb309..a9822eed89 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -4,6 +4,7 @@ #include "checkpoints.h" +#include "chain.h" #include "chainparams.h" #include "main.h" #include "uint256.h" @@ -15,30 +16,17 @@ namespace Checkpoints { /** - * How many times we expect transactions after the last checkpoint to - * be slower. This number is a compromise, as it can't be accurate for - * every system. When reindexing from a fast disk with a slow CPU, it + * How many times slower we expect checking transactions after the last + * checkpoint to be (from checking signatures, which is skipped up to the + * last checkpoint). This number is a compromise, as it can't be accurate + * for every system. When reindexing from a fast disk with a slow CPU, it * can be up to 20, while when downloading from a slow network with a * fast multicore CPU, it won't be much higher than 1. */ static const double SIGCHECK_VERIFICATION_FACTOR = 5.0; - bool fEnabled = true; - - bool CheckBlock(int nHeight, const uint256& hash) - { - if (!fEnabled) - return true; - - const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints; - - MapCheckpoints::const_iterator i = checkpoints.find(nHeight); - if (i == checkpoints.end()) return true; - return hash == i->second; - } - //! Guess how far we are in the verification process at the given block index - double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks) { + double GuessVerificationProgress(const CCheckpointData& data, CBlockIndex *pindex, bool fSigchecks) { if (pindex==NULL) return 0.0; @@ -50,8 +38,6 @@ namespace Checkpoints { // Work is defined as: 1.0 per transaction before the last checkpoint, and // fSigcheckVerificationFactor per transaction after. - const CCheckpointData &data = Params().Checkpoints(); - if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) { double nCheapBefore = pindex->nChainTx; double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx; @@ -69,22 +55,19 @@ namespace Checkpoints { return fWorkBefore / (fWorkBefore + fWorkAfter); } - int GetTotalBlocksEstimate() + int GetTotalBlocksEstimate(const CCheckpointData& data) { - if (!fEnabled) - return 0; + const MapCheckpoints& checkpoints = data.mapCheckpoints; - const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints; + if (checkpoints.empty()) + return 0; return checkpoints.rbegin()->first; } - CBlockIndex* GetLastCheckpoint() + CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) { - if (!fEnabled) - return NULL; - - const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints; + const MapCheckpoints& checkpoints = data.mapCheckpoints; BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints) { diff --git a/src/checkpoints.h b/src/checkpoints.h index 29dc5f83a9..5fce6fa81e 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -10,34 +10,22 @@ #include <map> class CBlockIndex; +struct CCheckpointData; -/** +/** * Block-chain checkpoints are compiled-in sanity checks. * They are updated every release or three. */ namespace Checkpoints { -typedef std::map<int, uint256> MapCheckpoints; - -struct CCheckpointData { - const MapCheckpoints *mapCheckpoints; - int64_t nTimeLastCheckpoint; - int64_t nTransactionsLastCheckpoint; - double fTransactionsPerDay; -}; - -//! Returns true if block passes checkpoint checks -bool CheckBlock(int nHeight, const uint256& hash); //! Return conservative estimate of total number of blocks, 0 if unknown -int GetTotalBlocksEstimate(); +int GetTotalBlocksEstimate(const CCheckpointData& data); //! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint -CBlockIndex* GetLastCheckpoint(); - -double GuessVerificationProgress(CBlockIndex* pindex, bool fSigchecks = true); +CBlockIndex* GetLastCheckpoint(const CCheckpointData& data); -extern bool fEnabled; +double GuessVerificationProgress(const CCheckpointData& data, CBlockIndex* pindex, bool fSigchecks = true); } //namespace Checkpoints diff --git a/src/checkqueue.h b/src/checkqueue.h index 6f6b97e3a7..20ba25bb41 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -54,7 +54,7 @@ private: /** * Number of verifications that haven't completed yet. - * This includes elements that are not anymore in queue, but still in + * This includes elements that are no longer queued, but still in the * worker's own batches. */ unsigned int nTodo; @@ -81,7 +81,7 @@ private: fAllOk &= fOk; nTodo -= nNow; if (nTodo == 0 && !fMaster) - // We processed the last element; inform the master he or she can exit and return the result + // We processed the last element; inform the master it can exit and return the result condMaster.notify_one(); } else { // first iteration @@ -136,7 +136,7 @@ public: Loop(); } - //! Wait until execution finishes, and return whether all evaluations where successful. + //! Wait until execution finishes, and return whether all evaluations were successful. bool Wait() { return Loop(true); diff --git a/src/clientversion.h b/src/clientversion.h index 3c8c969f9d..5a06b310a3 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 10 +#define CLIENT_VERSION_MINOR 11 #define CLIENT_VERSION_REVISION 99 #define CLIENT_VERSION_BUILD 0 diff --git a/src/coincontrol.h b/src/coincontrol.h index 92fae9847c..bc965f9e19 100644 --- a/src/coincontrol.h +++ b/src/coincontrol.h @@ -12,6 +12,10 @@ class CCoinControl { public: CTxDestination destChange; + //! If false, allows unselected inputs, but requires all selected inputs be used + bool fAllowOtherInputs; + //! Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria + bool fAllowWatchOnly; CCoinControl() { @@ -21,6 +25,8 @@ public: void SetNull() { destChange = CNoDestination(); + fAllowOtherInputs = false; + fAllowWatchOnly = false; setSelected.clear(); } @@ -50,7 +56,7 @@ public: setSelected.clear(); } - void ListSelected(std::vector<COutPoint>& vOutpoints) + void ListSelected(std::vector<COutPoint>& vOutpoints) const { vOutpoints.assign(setSelected.begin(), setSelected.end()); } diff --git a/src/coins.cpp b/src/coins.cpp index d79e29951b..f02949de53 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -4,6 +4,7 @@ #include "coins.h" +#include "memusage.h" #include "random.h" #include <assert.h> @@ -57,13 +58,17 @@ bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStat CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {} -CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false) { } +CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), cachedCoinsUsage(0) { } CCoinsViewCache::~CCoinsViewCache() { assert(!hasModifier); } +size_t CCoinsViewCache::DynamicMemoryUsage() const { + return memusage::DynamicUsage(cacheCoins) + cachedCoinsUsage; +} + CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const { CCoinsMap::iterator it = cacheCoins.find(txid); if (it != cacheCoins.end()) @@ -78,6 +83,7 @@ CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const // version as fresh. ret->second.flags = CCoinsCacheEntry::FRESH; } + cachedCoinsUsage += ret->second.coins.DynamicMemoryUsage(); return ret; } @@ -93,6 +99,7 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const { CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) { assert(!hasModifier); std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())); + size_t cachedCoinUsage = 0; if (ret.second) { if (!base->GetCoins(txid, ret.first->second.coins)) { // The parent view does not have this entry; mark it as fresh. @@ -102,10 +109,12 @@ CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) { // The parent view only has a pruned entry for this; mark it as fresh. ret.first->second.flags = CCoinsCacheEntry::FRESH; } + } else { + cachedCoinUsage = ret.first->second.coins.DynamicMemoryUsage(); } // Assume that whenever ModifyCoins is called, the entry will be modified. ret.first->second.flags |= CCoinsCacheEntry::DIRTY; - return CCoinsModifier(*this, ret.first); + return CCoinsModifier(*this, ret.first, cachedCoinUsage); } const CCoins* CCoinsViewCache::AccessCoins(const uint256 &txid) const { @@ -150,6 +159,7 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn assert(it->second.flags & CCoinsCacheEntry::FRESH); CCoinsCacheEntry& entry = cacheCoins[it->first]; entry.coins.swap(it->second.coins); + cachedCoinsUsage += entry.coins.DynamicMemoryUsage(); entry.flags = CCoinsCacheEntry::DIRTY | CCoinsCacheEntry::FRESH; } } else { @@ -157,10 +167,13 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn // The grandparent does not have an entry, and the child is // modified and being pruned. This means we can just delete // it from the parent. + cachedCoinsUsage -= itUs->second.coins.DynamicMemoryUsage(); cacheCoins.erase(itUs); } else { // A normal modification. + cachedCoinsUsage -= itUs->second.coins.DynamicMemoryUsage(); itUs->second.coins.swap(it->second.coins); + cachedCoinsUsage += itUs->second.coins.DynamicMemoryUsage(); itUs->second.flags |= CCoinsCacheEntry::DIRTY; } } @@ -175,6 +188,7 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn bool CCoinsViewCache::Flush() { bool fOk = base->BatchWrite(cacheCoins, hashBlock); cacheCoins.clear(); + cachedCoinsUsage = 0; return fOk; } @@ -232,7 +246,7 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const return tx.ComputePriority(dResult); } -CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_) : cache(cache_), it(it_) { +CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_, size_t usage) : cache(cache_), it(it_), cachedCoinUsage(usage) { assert(!cache.hasModifier); cache.hasModifier = true; } @@ -242,7 +256,11 @@ CCoinsModifier::~CCoinsModifier() assert(cache.hasModifier); cache.hasModifier = false; it->second.coins.Cleanup(); + cache.cachedCoinsUsage -= cachedCoinUsage; // Subtract the old usage if ((it->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) { cache.cacheCoins.erase(it); + } else { + // If the coin still exists after the modification, add the new usage + cache.cachedCoinsUsage += it->second.coins.DynamicMemoryUsage(); } } diff --git a/src/coins.h b/src/coins.h index fe2eaa08e5..bf4a777b8a 100644 --- a/src/coins.h +++ b/src/coins.h @@ -7,6 +7,8 @@ #define BITCOIN_COINS_H #include "compressor.h" +#include "core_memusage.h" +#include "memusage.h" #include "serialize.h" #include "uint256.h" @@ -252,6 +254,14 @@ public: return false; return true; } + + size_t DynamicMemoryUsage() const { + size_t ret = memusage::DynamicUsage(vout); + BOOST_FOREACH(const CTxOut &out, vout) { + ret += RecursiveDynamicUsage(out.scriptPubKey); + } + return ret; + } }; class CCoinsKeyHasher @@ -356,7 +366,8 @@ class CCoinsModifier private: CCoinsViewCache& cache; CCoinsMap::iterator it; - CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_); + size_t cachedCoinUsage; // Cached memory usage of the CCoins object before modification + CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_, size_t usage); public: CCoins* operator->() { return &it->second.coins; } @@ -372,6 +383,7 @@ protected: /* Whether this cache has an active modifier. */ bool hasModifier; + /** * Make mutable so that we can "fill the cache" even from Get-methods * declared as "const". @@ -379,6 +391,9 @@ protected: mutable uint256 hashBlock; mutable CCoinsMap cacheCoins; + /* Cached dynamic memory usage for the inner CCoins objects. */ + mutable size_t cachedCoinsUsage; + public: CCoinsViewCache(CCoinsView *baseIn); ~CCoinsViewCache(); @@ -414,6 +429,9 @@ public: //! Calculate the size of the cache (in number of transactions) unsigned int GetCacheSize() const; + //! Calculate the size of the cache (in bytes) + size_t DynamicMemoryUsage() const; + /** * Amount of bitcoins coming in to a transaction * Note that lightweight clients may not know anything besides the hash of previous transactions, diff --git a/src/compat.h b/src/compat.h index 7a5438a11e..5378c2c761 100644 --- a/src/compat.h +++ b/src/compat.h @@ -92,4 +92,12 @@ typedef u_int SOCKET; size_t strnlen( const char *start, size_t max_len); #endif // HAVE_DECL_STRNLEN +bool static inline IsSelectableSocket(SOCKET s) { +#ifdef WIN32 + return true; +#else + return (s < FD_SETSIZE); +#endif +} + #endif // BITCOIN_COMPAT_H diff --git a/src/compat/endian.h b/src/compat/endian.h index 4d041d6554..9fec2a07fa 100644 --- a/src/compat/endian.h +++ b/src/compat/endian.h @@ -15,6 +15,8 @@ #if defined(HAVE_ENDIAN_H) #include <endian.h> +#elif defined(HAVE_SYS_ENDIAN_H) +#include <sys/endian.h> #endif #if defined(WORDS_BIGENDIAN) diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index 9c5b7d4ffb..f937844e9f 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -12,7 +12,5 @@ static const unsigned int MAX_BLOCK_SIZE = 1000000; 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; -/** 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 #endif // BITCOIN_CONSENSUS_CONSENSUS_H diff --git a/src/consensus/validation.h b/src/consensus/validation.h new file mode 100644 index 0000000000..d6051edc38 --- /dev/null +++ b/src/consensus/validation.h @@ -0,0 +1,85 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// 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. + +#ifndef BITCOIN_CONSENSUS_VALIDATION_H +#define BITCOIN_CONSENSUS_VALIDATION_H + +#include <string> + +/** "reject" message codes */ +static const unsigned char REJECT_MALFORMED = 0x01; +static const unsigned char REJECT_INVALID = 0x10; +static const unsigned char REJECT_OBSOLETE = 0x11; +static const unsigned char REJECT_DUPLICATE = 0x12; +static const unsigned char REJECT_NONSTANDARD = 0x40; +static const unsigned char REJECT_DUST = 0x41; +static const unsigned char REJECT_INSUFFICIENTFEE = 0x42; +static const unsigned char REJECT_CHECKPOINT = 0x43; + +/** Capture information about block/transaction validation */ +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; + int nDoS; + std::string strRejectReason; + unsigned int chRejectCode; + bool corruptionPossible; + std::string strDebugMessage; +public: + CValidationState() : mode(MODE_VALID), nDoS(0), chRejectCode(0), corruptionPossible(false) {} + bool DoS(int level, bool ret = false, + unsigned int chRejectCodeIn=0, const std::string &strRejectReasonIn="", + bool corruptionIn=false, + const std::string &strDebugMessageIn="") { + chRejectCode = chRejectCodeIn; + strRejectReason = strRejectReasonIn; + corruptionPossible = corruptionIn; + strDebugMessage = strDebugMessageIn; + if (mode == MODE_ERROR) + return ret; + nDoS += level; + mode = MODE_INVALID; + return ret; + } + bool Invalid(bool ret = false, + unsigned int _chRejectCode=0, const std::string &_strRejectReason="", + const std::string &_strDebugMessage="") { + return DoS(0, ret, _chRejectCode, _strRejectReason, false, _strDebugMessage); + } + bool Error(const std::string& strRejectReasonIn) { + if (mode == MODE_VALID) + strRejectReason = strRejectReasonIn; + mode = MODE_ERROR; + return false; + } + bool IsValid() const { + return mode == MODE_VALID; + } + bool IsInvalid() const { + return mode == MODE_INVALID; + } + bool IsError() const { + return mode == MODE_ERROR; + } + bool IsInvalid(int &nDoSOut) const { + if (IsInvalid()) { + nDoSOut = nDoS; + return true; + } + return false; + } + bool CorruptionPossible() const { + return corruptionPossible; + } + unsigned int GetRejectCode() const { return chRejectCode; } + std::string GetRejectReason() const { return strRejectReason; } + std::string GetDebugMessage() const { return strDebugMessage; } +}; + +#endif // BITCOIN_CONSENSUS_VALIDATION_H diff --git a/src/core_io.h b/src/core_io.h index 0989cf7437..ba5b4e6487 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -15,7 +15,8 @@ class uint256; class UniValue; // core_read.cpp -extern CScript ParseScript(std::string s); +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 DecodeHexBlk(CBlock&, const std::string& strHexBlk); extern uint256 ParseHashUV(const UniValue& v, const std::string& strName); @@ -25,8 +26,7 @@ extern std::vector<unsigned char> 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 void ScriptPubKeyToUniv(const CScript& scriptPubKey, - UniValue& out, bool fIncludeHex); +extern void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); extern void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry); #endif // BITCOIN_CORE_IO_H diff --git a/src/core_memusage.h b/src/core_memusage.h new file mode 100644 index 0000000000..a05f59ee0c --- /dev/null +++ b/src/core_memusage.h @@ -0,0 +1,62 @@ +// 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_CORE_MEMUSAGE_H +#define BITCOIN_CORE_MEMUSAGE_H + +#include "primitives/transaction.h" +#include "primitives/block.h" +#include "memusage.h" + +static inline size_t RecursiveDynamicUsage(const CScript& script) { + return memusage::DynamicUsage(*static_cast<const std::vector<unsigned char>*>(&script)); +} + +static inline size_t RecursiveDynamicUsage(const COutPoint& out) { + return 0; +} + +static inline size_t RecursiveDynamicUsage(const CTxIn& in) { + return RecursiveDynamicUsage(in.scriptSig) + RecursiveDynamicUsage(in.prevout); +} + +static inline size_t RecursiveDynamicUsage(const CTxOut& out) { + return RecursiveDynamicUsage(out.scriptPubKey); +} + +static inline size_t RecursiveDynamicUsage(const CTransaction& tx) { + size_t mem = memusage::DynamicUsage(tx.vin) + memusage::DynamicUsage(tx.vout); + for (std::vector<CTxIn>::const_iterator it = tx.vin.begin(); it != tx.vin.end(); it++) { + mem += RecursiveDynamicUsage(*it); + } + for (std::vector<CTxOut>::const_iterator it = tx.vout.begin(); it != tx.vout.end(); it++) { + mem += RecursiveDynamicUsage(*it); + } + return mem; +} + +static inline size_t RecursiveDynamicUsage(const CMutableTransaction& tx) { + size_t mem = memusage::DynamicUsage(tx.vin) + memusage::DynamicUsage(tx.vout); + for (std::vector<CTxIn>::const_iterator it = tx.vin.begin(); it != tx.vin.end(); it++) { + mem += RecursiveDynamicUsage(*it); + } + for (std::vector<CTxOut>::const_iterator it = tx.vout.begin(); it != tx.vout.end(); it++) { + mem += RecursiveDynamicUsage(*it); + } + return mem; +} + +static inline size_t RecursiveDynamicUsage(const CBlock& block) { + size_t mem = memusage::DynamicUsage(block.vtx); + for (std::vector<CTransaction>::const_iterator it = block.vtx.begin(); it != block.vtx.end(); it++) { + mem += RecursiveDynamicUsage(*it); + } + return mem; +} + +static inline size_t RecursiveDynamicUsage(const CBlockLocator& locator) { + return memusage::DynamicUsage(locator.vHave); +} + +#endif // BITCOIN_CORE_MEMUSAGE_H diff --git a/src/core_read.cpp b/src/core_read.cpp index e064955ff0..f762f2c3b7 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -22,7 +22,7 @@ using namespace std; -CScript ParseScript(std::string s) +CScript ParseScript(const std::string& s) { CScript result; diff --git a/src/core_write.cpp b/src/core_write.cpp index c3babec2fc..2ad42baddf 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -15,6 +15,7 @@ #include "utilmoneystr.h" #include "utilstrencodings.h" +#include <boost/assign/list_of.hpp> #include <boost/foreach.hpp> using namespace std; @@ -54,6 +55,67 @@ string FormatScript(const CScript& script) return ret.substr(0, ret.size() - 1); } +const map<unsigned char, string> mapSigHashTypes = + boost::assign::map_list_of + (static_cast<unsigned char>(SIGHASH_ALL), string("ALL")) + (static_cast<unsigned char>(SIGHASH_ALL|SIGHASH_ANYONECANPAY), string("ALL|ANYONECANPAY")) + (static_cast<unsigned char>(SIGHASH_NONE), string("NONE")) + (static_cast<unsigned char>(SIGHASH_NONE|SIGHASH_ANYONECANPAY), string("NONE|ANYONECANPAY")) + (static_cast<unsigned char>(SIGHASH_SINGLE), string("SINGLE")) + (static_cast<unsigned char>(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY), string("SINGLE|ANYONECANPAY")) + ; + +/** + * Create the assembly string representation of a CScript object. + * @param[in] script CScript object to convert into the asm string representation. + * @param[in] fAttemptSighashDecode Whether to attempt to decode sighash types on data within the script that matches the format + * of a signature. Only pass true for scripts you believe could contain signatures. For example, + * pass false, or omit the this argument (defaults to false), for scriptPubKeys. + */ +string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode) +{ + string str; + opcodetype opcode; + vector<unsigned char> vch; + CScript::const_iterator pc = script.begin(); + while (pc < script.end()) { + if (!str.empty()) { + str += " "; + } + if (!script.GetOp(pc, opcode, vch)) { + str += "[error]"; + return str; + } + if (0 <= opcode && opcode <= OP_PUSHDATA4) { + if (vch.size() <= static_cast<vector<unsigned char>::size_type>(4)) { + str += strprintf("%d", CScriptNum(vch, false).getint()); + } else { + // the IsUnspendable check makes sure not to try to decode OP_RETURN data that may match the format of a signature + if (fAttemptSighashDecode && !script.IsUnspendable()) { + string strSigHashDecode; + // goal: only attempt to decode a defined sighash type from data that looks like a signature within a scriptSig. + // this won't decode correctly formatted public keys in Pubkey or Multisig scripts due to + // the restrictions on the pubkey formats (see IsCompressedOrUncompressedPubKey) being incongruous with the + // checks in CheckSignatureEncoding. + if (CheckSignatureEncoding(vch, SCRIPT_VERIFY_STRICTENC, NULL)) { + const unsigned char chSigHashType = vch.back(); + if (mapSigHashTypes.count(chSigHashType)) { + strSigHashDecode = "[" + mapSigHashTypes.find(chSigHashType)->second + "]"; + vch.pop_back(); // remove the sighash type byte. it will be replaced by the decode. + } + } + str += HexStr(vch) + strSigHashDecode; + } else { + str += HexStr(vch); + } + } + } else { + str += GetOpName(opcode); + } + } + return str; +} + string EncodeHexTx(const CTransaction& tx) { CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); @@ -68,7 +130,7 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey, vector<CTxDestination> addresses; int nRequired; - out.pushKV("asm", scriptPubKey.ToString()); + out.pushKV("asm", ScriptToAsmStr(scriptPubKey)); if (fIncludeHex) out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())); @@ -101,7 +163,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry) in.pushKV("txid", txin.prevout.hash.GetHex()); in.pushKV("vout", (int64_t)txin.prevout.n); UniValue o(UniValue::VOBJ); - o.pushKV("asm", txin.scriptSig.ToString()); + o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true)); o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); in.pushKV("scriptSig", o); } diff --git a/src/ecwrapper.cpp b/src/ecwrapper.cpp index 5e3aec25ba..f94bc954fd 100644 --- a/src/ecwrapper.cpp +++ b/src/ecwrapper.cpp @@ -13,6 +13,29 @@ namespace { +class ecgroup_order +{ +public: + static const EC_GROUP* get() + { + static const ecgroup_order wrapper; + return wrapper.pgroup; + } + +private: + ecgroup_order() + : pgroup(EC_GROUP_new_by_curve_name(NID_secp256k1)) + { + } + + ~ecgroup_order() + { + EC_GROUP_free(pgroup); + } + + EC_GROUP* pgroup; +}; + /** * Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields * recid selects which key is recovered @@ -92,8 +115,10 @@ err: } // anon namespace CECKey::CECKey() { - pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + pkey = EC_KEY_new(); assert(pkey != NULL); + int result = EC_KEY_set_group(pkey, ecgroup_order::get()); + assert(result); } CECKey::~CECKey() { @@ -185,11 +210,9 @@ bool CECKey::TweakPublic(const unsigned char vchTweak[32]) { bool CECKey::SanityCheck() { - EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1); - if(pkey == NULL) + const EC_GROUP *pgroup = ecgroup_order::get(); + if(pgroup == NULL) return false; - EC_KEY_free(pkey); - // TODO Is there more EC functionality that could be missing? return true; } diff --git a/src/hash.cpp b/src/hash.cpp index 20d5d21777..9711293e38 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -5,6 +5,7 @@ #include "hash.h" #include "crypto/common.h" #include "crypto/hmac_sha512.h" +#include "pubkey.h" inline uint32_t ROTL32(uint32_t x, int8_t r) @@ -71,15 +72,12 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char return h1; } -void BIP32Hash(const unsigned char chainCode[32], unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]) +void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]) { unsigned char num[4]; num[0] = (nChild >> 24) & 0xFF; num[1] = (nChild >> 16) & 0xFF; num[2] = (nChild >> 8) & 0xFF; num[3] = (nChild >> 0) & 0xFF; - CHMAC_SHA512(chainCode, 32).Write(&header, 1) - .Write(data, 32) - .Write(num, 4) - .Finalize(output); + CHMAC_SHA512(chainCode.begin(), chainCode.size()).Write(&header, 1).Write(data, 32).Write(num, 4).Finalize(output); } diff --git a/src/hash.h b/src/hash.h index e56b784a61..0771555623 100644 --- a/src/hash.h +++ b/src/hash.h @@ -14,6 +14,8 @@ #include <vector> +typedef uint256 ChainCode; + /** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */ class CHash256 { private: @@ -159,6 +161,6 @@ uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash); -void BIP32Hash(const unsigned char chainCode[32], unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]); +void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]); #endif // BITCOIN_HASH_H diff --git a/src/httprpc.cpp b/src/httprpc.cpp new file mode 100644 index 0000000000..98ac750bb1 --- /dev/null +++ b/src/httprpc.cpp @@ -0,0 +1,193 @@ +#include "httprpc.h" + +#include "base58.h" +#include "chainparams.h" +#include "httpserver.h" +#include "rpcprotocol.h" +#include "rpcserver.h" +#include "random.h" +#include "sync.h" +#include "util.h" +#include "utilstrencodings.h" +#include "ui_interface.h" + +#include <boost/algorithm/string.hpp> // boost::trim + +/** Simple one-shot callback timer to be used by the RPC mechanism to e.g. + * re-lock the wellet. + */ +class HTTPRPCTimer : public RPCTimerBase +{ +public: + HTTPRPCTimer(struct event_base* eventBase, boost::function<void(void)>& func, int64_t millis) : + ev(eventBase, false, func) + { + struct timeval tv; + tv.tv_sec = millis/1000; + tv.tv_usec = (millis%1000)*1000; + ev.trigger(&tv); + } +private: + HTTPEvent ev; +}; + +class HTTPRPCTimerInterface : public RPCTimerInterface +{ +public: + HTTPRPCTimerInterface(struct event_base* base) : base(base) + { + } + const char* Name() + { + return "HTTP"; + } + RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis) + { + return new HTTPRPCTimer(base, func, millis); + } +private: + struct event_base* base; +}; + + +/* Pre-base64-encoded authentication token */ +static std::string strRPCUserColonPass; +/* Stored RPC timer interface (for unregistration) */ +static HTTPRPCTimerInterface* httpRPCTimerInterface = 0; + +static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const UniValue& id) +{ + // Send error reply from json-rpc error object + int nStatus = HTTP_INTERNAL_SERVER_ERROR; + int code = find_value(objError, "code").get_int(); + + if (code == RPC_INVALID_REQUEST) + nStatus = HTTP_BAD_REQUEST; + else if (code == RPC_METHOD_NOT_FOUND) + nStatus = HTTP_NOT_FOUND; + + std::string strReply = JSONRPCReply(NullUniValue, objError, id); + + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(nStatus, strReply); +} + +static bool RPCAuthorized(const std::string& strAuth) +{ + if (strRPCUserColonPass.empty()) // Belt-and-suspenders measure if InitRPCAuthentication was not called + return false; + if (strAuth.substr(0, 6) != "Basic ") + return false; + std::string strUserPass64 = strAuth.substr(6); + boost::trim(strUserPass64); + std::string strUserPass = DecodeBase64(strUserPass64); + return TimingResistantEqual(strUserPass, strRPCUserColonPass); +} + +static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) +{ + // JSONRPC handles only POST + if (req->GetRequestMethod() != HTTPRequest::POST) { + req->WriteReply(HTTP_BAD_METHOD, "JSONRPC server handles only POST requests"); + return false; + } + // Check authorization + std::pair<bool, std::string> authHeader = req->GetHeader("authorization"); + if (!authHeader.first) { + req->WriteReply(HTTP_UNAUTHORIZED); + return false; + } + + if (!RPCAuthorized(authHeader.second)) { + LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", req->GetPeer().ToString()); + + /* Deter brute-forcing + If this results in a DoS the user really + shouldn't have their RPC port exposed. */ + MilliSleep(250); + + req->WriteReply(HTTP_UNAUTHORIZED); + return false; + } + + JSONRequest jreq; + try { + // Parse request + UniValue valRequest; + if (!valRequest.read(req->ReadBody())) + throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); + + std::string strReply; + // singleton request + if (valRequest.isObject()) { + jreq.parse(valRequest); + + UniValue result = tableRPC.execute(jreq.strMethod, jreq.params); + + // Send reply + strReply = JSONRPCReply(result, NullUniValue, jreq.id); + + // array of requests + } else if (valRequest.isArray()) + strReply = JSONRPCExecBatch(valRequest.get_array()); + else + throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error"); + + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strReply); + } catch (const UniValue& objError) { + JSONErrorReply(req, objError, jreq.id); + return false; + } catch (const std::exception& e) { + JSONErrorReply(req, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); + return false; + } + return true; +} + +static bool InitRPCAuthentication() +{ + if (mapArgs["-rpcpassword"] == "") + { + LogPrintf("No rpcpassword set - using random cookie authentication\n"); + if (!GenerateAuthCookie(&strRPCUserColonPass)) { + uiInterface.ThreadSafeMessageBox( + _("Error: A fatal internal error occurred, see debug.log for details"), // Same message as AbortNode + "", CClientUIInterface::MSG_ERROR); + return false; + } + } else { + strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; + } + return true; +} + +bool StartHTTPRPC() +{ + LogPrint("rpc", "Starting HTTP RPC server\n"); + if (!InitRPCAuthentication()) + return false; + + RegisterHTTPHandler("/", true, HTTPReq_JSONRPC); + + assert(EventBase()); + httpRPCTimerInterface = new HTTPRPCTimerInterface(EventBase()); + RPCRegisterTimerInterface(httpRPCTimerInterface); + return true; +} + +void InterruptHTTPRPC() +{ + LogPrint("rpc", "Interrupting HTTP RPC server\n"); +} + +void StopHTTPRPC() +{ + LogPrint("rpc", "Stopping HTTP RPC server\n"); + UnregisterHTTPHandler("/", true); + if (httpRPCTimerInterface) { + RPCUnregisterTimerInterface(httpRPCTimerInterface); + delete httpRPCTimerInterface; + httpRPCTimerInterface = 0; + } +} diff --git a/src/httprpc.h b/src/httprpc.h new file mode 100644 index 0000000000..d354457188 --- /dev/null +++ b/src/httprpc.h @@ -0,0 +1,37 @@ +// 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_HTTPRPC_H +#define BITCOIN_HTTPRPC_H + +#include <string> +#include <map> + +class HTTPRequest; + +/** Start HTTP RPC subsystem. + * Precondition; HTTP and RPC has been started. + */ +bool StartHTTPRPC(); +/** Interrupt HTTP RPC subsystem. + */ +void InterruptHTTPRPC(); +/** Stop HTTP RPC subsystem. + * Precondition; HTTP and RPC has been stopped. + */ +void StopHTTPRPC(); + +/** Start HTTP REST subsystem. + * Precondition; HTTP and RPC has been started. + */ +bool StartREST(); +/** Interrupt RPC REST subsystem. + */ +void InterruptREST(); +/** Stop HTTP REST subsystem. + * Precondition; HTTP and RPC has been stopped. + */ +void StopREST(); + +#endif diff --git a/src/httpserver.cpp b/src/httpserver.cpp new file mode 100644 index 0000000000..0a7f903e9f --- /dev/null +++ b/src/httpserver.cpp @@ -0,0 +1,650 @@ +// 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 "httpserver.h" + +#include "chainparamsbase.h" +#include "compat.h" +#include "util.h" +#include "netbase.h" +#include "rpcprotocol.h" // For HTTP status codes +#include "sync.h" +#include "ui_interface.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <signal.h> + +#include <event2/event.h> +#include <event2/http.h> +#include <event2/thread.h> +#include <event2/buffer.h> +#include <event2/util.h> +#include <event2/keyvalq_struct.h> + +#ifdef EVENT__HAVE_NETINET_IN_H +#include <netinet/in.h> +#ifdef _XOPEN_SOURCE_EXTENDED +#include <arpa/inet.h> +#endif +#endif + +#include <boost/algorithm/string/case_conv.hpp> // for to_lower() +#include <boost/foreach.hpp> +#include <boost/scoped_ptr.hpp> + +/** HTTP request work item */ +class HTTPWorkItem : public HTTPClosure +{ +public: + HTTPWorkItem(HTTPRequest* req, const std::string &path, const HTTPRequestHandler& func): + req(req), path(path), func(func) + { + } + void operator()() + { + func(req.get(), path); + } + + boost::scoped_ptr<HTTPRequest> req; + +private: + std::string path; + HTTPRequestHandler func; +}; + +/** Simple work queue for distributing work over multiple threads. + * Work items are simply callable objects. + */ +template <typename WorkItem> +class WorkQueue +{ +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<WorkItem*> queue; + bool running; + size_t maxDepth; + int numThreads; + + /** RAII object to keep track of number of running worker threads */ + class ThreadCounter + { + public: + WorkQueue &wq; + ThreadCounter(WorkQueue &w): wq(w) + { + boost::lock_guard<boost::mutex> lock(wq.cs); + wq.numThreads += 1; + } + ~ThreadCounter() + { + boost::lock_guard<boost::mutex> lock(wq.cs); + wq.numThreads -= 1; + wq.cond.notify_all(); + } + }; + +public: + WorkQueue(size_t maxDepth) : running(true), + maxDepth(maxDepth), + numThreads(0) + { + } + /*( 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) + { + boost::unique_lock<boost::mutex> lock(cs); + if (queue.size() >= maxDepth) { + return false; + } + queue.push_back(item); + cond.notify_one(); + return true; + } + /** Thread function */ + void Run() + { + ThreadCounter count(*this); + while (running) { + WorkItem* i = 0; + { + boost::unique_lock<boost::mutex> lock(cs); + while (running && queue.empty()) + cond.wait(lock); + if (!running) + break; + i = queue.front(); + queue.pop_front(); + } + (*i)(); + delete i; + } + } + /** Interrupt and exit loops */ + void Interrupt() + { + boost::unique_lock<boost::mutex> lock(cs); + running = false; + cond.notify_all(); + } + /** Wait for worker threads to exit */ + void WaitExit() + { + boost::unique_lock<boost::mutex> lock(cs); + while (numThreads > 0) + cond.wait(lock); + } + + /** Return current depth of queue */ + size_t Depth() + { + boost::unique_lock<boost::mutex> lock(cs); + return queue.size(); + } +}; + +struct HTTPPathHandler +{ + HTTPPathHandler() {} + HTTPPathHandler(std::string prefix, bool exactMatch, HTTPRequestHandler handler): + prefix(prefix), exactMatch(exactMatch), handler(handler) + { + } + std::string prefix; + bool exactMatch; + HTTPRequestHandler handler; +}; + +/** HTTP module state */ + +//! libevent event loop +static struct event_base* eventBase = 0; +//! HTTP server +struct evhttp* eventHTTP = 0; +//! List of subnets to allow RPC connections from +static std::vector<CSubNet> rpc_allow_subnets; +//! Work queue for handling longer requests off the event loop thread +static WorkQueue<HTTPClosure>* workQueue = 0; +//! Handlers for (sub)paths +std::vector<HTTPPathHandler> pathHandlers; +//! Bound listening sockets +std::vector<evhttp_bound_socket *> boundSockets; + +/** Check if a network address is allowed to access the HTTP server */ +static bool ClientAllowed(const CNetAddr& netaddr) +{ + if (!netaddr.IsValid()) + return false; + BOOST_FOREACH (const CSubNet& subnet, rpc_allow_subnets) + if (subnet.Match(netaddr)) + return true; + return false; +} + +/** Initialize ACL list for HTTP server */ +static bool InitHTTPAllowList() +{ + rpc_allow_subnets.clear(); + rpc_allow_subnets.push_back(CSubNet("127.0.0.0/8")); // always allow IPv4 local subnet + rpc_allow_subnets.push_back(CSubNet("::1")); // always allow IPv6 localhost + if (mapMultiArgs.count("-rpcallowip")) { + const std::vector<std::string>& vAllow = mapMultiArgs["-rpcallowip"]; + BOOST_FOREACH (std::string strAllow, vAllow) { + CSubNet subnet(strAllow); + if (!subnet.IsValid()) { + uiInterface.ThreadSafeMessageBox( + strprintf("Invalid -rpcallowip subnet specification: %s. Valid 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).", strAllow), + "", CClientUIInterface::MSG_ERROR); + return false; + } + rpc_allow_subnets.push_back(subnet); + } + } + std::string strAllowed; + BOOST_FOREACH (const CSubNet& subnet, rpc_allow_subnets) + strAllowed += subnet.ToString() + " "; + LogPrint("http", "Allowing HTTP connections from: %s\n", strAllowed); + return true; +} + +/** HTTP request method as string - use for logging only */ +static std::string RequestMethodString(HTTPRequest::RequestMethod m) +{ + switch (m) { + case HTTPRequest::GET: + return "GET"; + break; + case HTTPRequest::POST: + return "POST"; + break; + case HTTPRequest::HEAD: + return "HEAD"; + break; + case HTTPRequest::PUT: + return "PUT"; + break; + default: + return "unknown"; + } +} + +/** HTTP request callback */ +static void http_request_cb(struct evhttp_request* req, void* arg) +{ + std::auto_ptr<HTTPRequest> hreq(new HTTPRequest(req)); + + LogPrint("http", "Received a %s request for %s from %s\n", + RequestMethodString(hreq->GetRequestMethod()), hreq->GetURI(), hreq->GetPeer().ToString()); + + // Early address-based allow check + if (!ClientAllowed(hreq->GetPeer())) { + hreq->WriteReply(HTTP_FORBIDDEN); + return; + } + + // Early reject unknown HTTP methods + if (hreq->GetRequestMethod() == HTTPRequest::UNKNOWN) { + hreq->WriteReply(HTTP_BADMETHOD); + return; + } + + // Find registered handler for prefix + std::string strURI = hreq->GetURI(); + std::string path; + std::vector<HTTPPathHandler>::const_iterator i = pathHandlers.begin(); + std::vector<HTTPPathHandler>::const_iterator iend = pathHandlers.end(); + for (; i != iend; ++i) { + bool match = false; + if (i->exactMatch) + match = (strURI == i->prefix); + else + match = (strURI.substr(0, i->prefix.size()) == i->prefix); + if (match) { + path = strURI.substr(i->prefix.size()); + break; + } + } + + // Dispatch to worker thread + if (i != iend) { + std::auto_ptr<HTTPWorkItem> item(new HTTPWorkItem(hreq.release(), path, i->handler)); + assert(workQueue); + if (workQueue->Enqueue(item.get())) + item.release(); /* if true, queue took ownership */ + else + item->req->WriteReply(HTTP_INTERNAL, "Work queue depth exceeded"); + } else { + hreq->WriteReply(HTTP_NOTFOUND); + } +} + +/** Callback to reject HTTP requests after shutdown. */ +static void http_reject_request_cb(struct evhttp_request* req, void*) +{ + LogPrint("http", "Rejecting request while shutting down\n"); + evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL); +} + +/** Event dispatcher thread */ +static void ThreadHTTP(struct event_base* base, struct evhttp* http) +{ + RenameThread("bitcoin-http"); + LogPrint("http", "Entering http event loop\n"); + event_base_dispatch(base); + // Event loop will be interrupted by InterruptHTTPServer() + LogPrint("http", "Exited http event loop\n"); +} + +/** Bind HTTP server to specified addresses */ +static bool HTTPBindAddresses(struct evhttp* http) +{ + int defaultPort = GetArg("-rpcport", BaseParams().RPCPort()); + std::vector<std::pair<std::string, uint16_t> > endpoints; + + // Determine what addresses to bind to + if (!mapArgs.count("-rpcallowip")) { // Default to loopback if not allowing external IPs + endpoints.push_back(std::make_pair("::1", defaultPort)); + endpoints.push_back(std::make_pair("127.0.0.1", defaultPort)); + if (mapArgs.count("-rpcbind")) { + LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n"); + } + } else if (mapArgs.count("-rpcbind")) { // Specific bind address + const std::vector<std::string>& vbind = mapMultiArgs["-rpcbind"]; + for (std::vector<std::string>::const_iterator i = vbind.begin(); i != vbind.end(); ++i) { + int port = defaultPort; + std::string host; + SplitHostPort(*i, port, host); + endpoints.push_back(std::make_pair(host, port)); + } + } else { // No specific bind address specified, bind to any + endpoints.push_back(std::make_pair("::", defaultPort)); + endpoints.push_back(std::make_pair("0.0.0.0", defaultPort)); + } + + // Bind addresses + for (std::vector<std::pair<std::string, uint16_t> >::iterator i = endpoints.begin(); i != endpoints.end(); ++i) { + LogPrint("http", "Binding RPC on address %s port %i\n", i->first, i->second); + evhttp_bound_socket *bind_handle = evhttp_bind_socket_with_handle(http, i->first.empty() ? NULL : i->first.c_str(), i->second); + if (bind_handle) { + boundSockets.push_back(bind_handle); + } else { + LogPrintf("Binding RPC on address %s port %i failed.\n", i->first, i->second); + } + } + return !boundSockets.empty(); +} + +/** Simple wrapper to set thread name and run work queue */ +static void HTTPWorkQueueRun(WorkQueue<HTTPClosure>* queue) +{ + RenameThread("bitcoin-httpworker"); + queue->Run(); +} + +/** libevent event log callback */ +static void libevent_log_cb(int severity, const char *msg) +{ + if (severity >= EVENT_LOG_WARN) // Log warn messages and higher without debug category + LogPrintf("libevent: %s\n", msg); + else + LogPrint("libevent", "libevent: %s\n", msg); +} + +bool InitHTTPServer() +{ + struct evhttp* http = 0; + struct event_base* base = 0; + + if (!InitHTTPAllowList()) + return false; + + if (GetBoolArg("-rpcssl", false)) { + uiInterface.ThreadSafeMessageBox( + "SSL mode for RPC (-rpcssl) is no longer supported.", + "", CClientUIInterface::MSG_ERROR); + return false; + } + + // Redirect libevent's logging to our own log + event_set_log_callback(&libevent_log_cb); +#if LIBEVENT_VERSION_NUMBER >= 0x02010100 + // If -debug=libevent, set full libevent debugging. + // Otherwise, disable all libevent debugging. + if (LogAcceptCategory("libevent")) + event_enable_debug_logging(EVENT_DBG_ALL); + else + event_enable_debug_logging(EVENT_DBG_NONE); +#endif +#ifdef WIN32 + evthread_use_windows_threads(); +#else + evthread_use_pthreads(); +#endif + + base = event_base_new(); // XXX RAII + if (!base) { + LogPrintf("Couldn't create an event_base: exiting\n"); + return false; + } + + /* Create a new evhttp object to handle requests. */ + http = evhttp_new(base); // XXX RAII + if (!http) { + LogPrintf("couldn't create evhttp. Exiting.\n"); + event_base_free(base); + return false; + } + + evhttp_set_timeout(http, GetArg("-rpcservertimeout", DEFAULT_HTTP_SERVER_TIMEOUT)); + evhttp_set_max_body_size(http, MAX_SIZE); + evhttp_set_gencb(http, http_request_cb, NULL); + + if (!HTTPBindAddresses(http)) { + LogPrintf("Unable to bind any endpoint for RPC server\n"); + evhttp_free(http); + event_base_free(base); + return false; + } + + LogPrint("http", "Initialized HTTP server\n"); + int workQueueDepth = std::max((long)GetArg("-rpcworkqueue", DEFAULT_HTTP_WORKQUEUE), 1L); + LogPrintf("HTTP: creating work queue of depth %d\n", workQueueDepth); + + workQueue = new WorkQueue<HTTPClosure>(workQueueDepth); + eventBase = base; + eventHTTP = http; + return true; +} + +bool StartHTTPServer(boost::thread_group& threadGroup) +{ + LogPrint("http", "Starting HTTP server\n"); + int rpcThreads = std::max((long)GetArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1L); + LogPrintf("HTTP: starting %d worker threads\n", rpcThreads); + threadGroup.create_thread(boost::bind(&ThreadHTTP, eventBase, eventHTTP)); + + for (int i = 0; i < rpcThreads; i++) + threadGroup.create_thread(boost::bind(&HTTPWorkQueueRun, workQueue)); + return true; +} + +void InterruptHTTPServer() +{ + LogPrint("http", "Interrupting HTTP server\n"); + if (eventHTTP) { + // Unlisten sockets + BOOST_FOREACH (evhttp_bound_socket *socket, boundSockets) { + evhttp_del_accept_socket(eventHTTP, socket); + } + // Reject requests on current connections + evhttp_set_gencb(eventHTTP, http_reject_request_cb, NULL); + } + if (eventBase) { + // Force-exit event loop after predefined time + struct timeval tv; + tv.tv_sec = 10; + tv.tv_usec = 0; + event_base_loopexit(eventBase, &tv); + } + if (workQueue) + workQueue->Interrupt(); +} + +void StopHTTPServer() +{ + LogPrint("http", "Stopping HTTP server\n"); + if (workQueue) { + LogPrint("http", "Waiting for HTTP worker threads to exit\n"); + workQueue->WaitExit(); + delete workQueue; + } + if (eventHTTP) { + evhttp_free(eventHTTP); + eventHTTP = 0; + } + if (eventBase) { + event_base_free(eventBase); + eventBase = 0; + } +} + +struct event_base* EventBase() +{ + return eventBase; +} + +static void httpevent_callback_fn(evutil_socket_t, short, void* data) +{ + // Static handler: simply call inner handler + HTTPEvent *self = ((HTTPEvent*)data); + self->handler(); + if (self->deleteWhenTriggered) + delete self; +} + +HTTPEvent::HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const boost::function<void(void)>& handler): + deleteWhenTriggered(deleteWhenTriggered), handler(handler) +{ + ev = event_new(base, -1, 0, httpevent_callback_fn, this); + assert(ev); +} +HTTPEvent::~HTTPEvent() +{ + event_free(ev); +} +void HTTPEvent::trigger(struct timeval* tv) +{ + if (tv == NULL) + event_active(ev, 0, 0); // immediately trigger event in main thread + else + evtimer_add(ev, tv); // trigger after timeval passed +} +HTTPRequest::HTTPRequest(struct evhttp_request* req) : req(req), + replySent(false) +{ +} +HTTPRequest::~HTTPRequest() +{ + if (!replySent) { + // Keep track of whether reply was sent to avoid request leaks + LogPrintf("%s: Unhandled request\n", __func__); + WriteReply(HTTP_INTERNAL, "Unhandled request"); + } + // evhttpd cleans up the request, as long as a reply was sent. +} + +std::pair<bool, std::string> HTTPRequest::GetHeader(const std::string& hdr) +{ + const struct evkeyvalq* headers = evhttp_request_get_input_headers(req); + assert(headers); + const char* val = evhttp_find_header(headers, hdr.c_str()); + if (val) + return std::make_pair(true, val); + else + return std::make_pair(false, ""); +} + +std::string HTTPRequest::ReadBody() +{ + struct evbuffer* buf = evhttp_request_get_input_buffer(req); + if (!buf) + return ""; + size_t size = evbuffer_get_length(buf); + /** Trivial implementation: if this is ever a performance bottleneck, + * internal copying can be avoided in multi-segment buffers by using + * evbuffer_peek and an awkward loop. Though in that case, it'd be even + * better to not copy into an intermediate string but use a stream + * abstraction to consume the evbuffer on the fly in the parsing algorithm. + */ + const char* data = (const char*)evbuffer_pullup(buf, size); + if (!data) // returns NULL in case of empty buffer + return ""; + std::string rv(data, size); + evbuffer_drain(buf, size); + return rv; +} + +void HTTPRequest::WriteHeader(const std::string& hdr, const std::string& value) +{ + struct evkeyvalq* headers = evhttp_request_get_output_headers(req); + assert(headers); + evhttp_add_header(headers, hdr.c_str(), value.c_str()); +} + +/** Closure sent to main thread to request a reply to be sent to + * a HTTP request. + * Replies must be sent in the main loop in the main http thread, + * this cannot be done from worker threads. + */ +void HTTPRequest::WriteReply(int nStatus, const std::string& strReply) +{ + assert(!replySent && req); + // Send event to main http thread to send reply message + struct evbuffer* evb = evhttp_request_get_output_buffer(req); + assert(evb); + evbuffer_add(evb, strReply.data(), strReply.size()); + HTTPEvent* ev = new HTTPEvent(eventBase, true, + boost::bind(evhttp_send_reply, req, nStatus, (const char*)NULL, (struct evbuffer *)NULL)); + ev->trigger(0); + replySent = true; + req = 0; // transferred back to main thread +} + +CService HTTPRequest::GetPeer() +{ + evhttp_connection* con = evhttp_request_get_connection(req); + CService peer; + if (con) { + // evhttp retains ownership over returned address string + const char* address = ""; + uint16_t port = 0; + evhttp_connection_get_peer(con, (char**)&address, &port); + peer = CService(address, port); + } + return peer; +} + +std::string HTTPRequest::GetURI() +{ + return evhttp_request_get_uri(req); +} + +HTTPRequest::RequestMethod HTTPRequest::GetRequestMethod() +{ + switch (evhttp_request_get_command(req)) { + case EVHTTP_REQ_GET: + return GET; + break; + case EVHTTP_REQ_POST: + return POST; + break; + case EVHTTP_REQ_HEAD: + return HEAD; + break; + case EVHTTP_REQ_PUT: + return PUT; + break; + default: + return UNKNOWN; + break; + } +} + +void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler) +{ + LogPrint("http", "Registering HTTP handler for %s (exactmatch %d)\n", prefix, exactMatch); + pathHandlers.push_back(HTTPPathHandler(prefix, exactMatch, handler)); +} + +void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch) +{ + std::vector<HTTPPathHandler>::iterator i = pathHandlers.begin(); + std::vector<HTTPPathHandler>::iterator iend = pathHandlers.end(); + for (; i != iend; ++i) + if (i->prefix == prefix && i->exactMatch == exactMatch) + break; + if (i != iend) + { + LogPrint("http", "Unregistering HTTP handler for %s (exactmatch %d)\n", prefix, exactMatch); + pathHandlers.erase(i); + } +} + diff --git a/src/httpserver.h b/src/httpserver.h new file mode 100644 index 0000000000..b377dc19fc --- /dev/null +++ b/src/httpserver.h @@ -0,0 +1,149 @@ +// 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_HTTPSERVER_H +#define BITCOIN_HTTPSERVER_H + +#include <string> +#include <stdint.h> +#include <boost/thread.hpp> +#include <boost/scoped_ptr.hpp> +#include <boost/function.hpp> + +static const int DEFAULT_HTTP_THREADS=4; +static const int DEFAULT_HTTP_WORKQUEUE=16; +static const int DEFAULT_HTTP_SERVER_TIMEOUT=30; + +struct evhttp_request; +struct event_base; +class CService; +class HTTPRequest; + +/** Initialize HTTP server. + * Call this before RegisterHTTPHandler or EventBase(). + */ +bool InitHTTPServer(); +/** Start HTTP server. + * This is separate from InitHTTPServer to give users race-condition-free time + * to register their handlers between InitHTTPServer and StartHTTPServer. + */ +bool StartHTTPServer(boost::thread_group& threadGroup); +/** Interrupt HTTP server threads */ +void InterruptHTTPServer(); +/** Stop HTTP server */ +void StopHTTPServer(); + +/** Handler for requests to a certain HTTP path */ +typedef boost::function<void(HTTPRequest* req, const std::string &)> HTTPRequestHandler; +/** Register handler for prefix. + * If multiple handlers match a prefix, the first-registered one will + * be invoked. + */ +void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler); +/** Unregister handler for prefix */ +void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch); + +/** Return evhttp event base. This can be used by submodules to + * queue timers or custom events. + */ +struct event_base* EventBase(); + +/** In-flight HTTP request. + * Thin C++ wrapper around evhttp_request. + */ +class HTTPRequest +{ +private: + struct evhttp_request* req; + bool replySent; + +public: + HTTPRequest(struct evhttp_request* req); + ~HTTPRequest(); + + enum RequestMethod { + UNKNOWN, + GET, + POST, + HEAD, + PUT + }; + + /** Get requested URI. + */ + std::string GetURI(); + + /** Get CService (address:ip) for the origin of the http request. + */ + CService GetPeer(); + + /** Get request method. + */ + RequestMethod GetRequestMethod(); + + /** + * Get the request header specified by hdr, or an empty string. + * Return an pair (isPresent,string). + */ + std::pair<bool, std::string> GetHeader(const std::string& hdr); + + /** + * Read request body. + * + * @note As this consumes the underlying buffer, call this only once. + * Repeated calls will return an empty string. + */ + std::string ReadBody(); + + /** + * Write output header. + * + * @note call this before calling WriteErrorReply or Reply. + */ + void WriteHeader(const std::string& hdr, const std::string& value); + + /** + * Write HTTP reply. + * nStatus is the HTTP status code to send. + * strReply is the body of the reply. Keep it empty to send a standard message. + * + * @note Can be called only once. As this will give the request back to the + * main thread, do not call any other HTTPRequest methods after calling this. + */ + void WriteReply(int nStatus, const std::string& strReply = ""); +}; + +/** Event handler closure. + */ +class HTTPClosure +{ +public: + virtual void operator()() = 0; + virtual ~HTTPClosure() {} +}; + +/** Event class. This can be used either as an cross-thread trigger or as a timer. + */ +class HTTPEvent +{ +public: + /** Create a new event. + * deleteWhenTriggered deletes this event object after the event is triggered (and the handler called) + * handler is the handler to call when the event is triggered. + */ + HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const boost::function<void(void)>& handler); + ~HTTPEvent(); + + /** Trigger the event. If tv is 0, trigger it immediately. Otherwise trigger it after + * the given time has elapsed. + */ + void trigger(struct timeval* tv); + + bool deleteWhenTriggered; + boost::function<void(void)> handler; +private: + struct event* ev; +}; + +#endif // BITCOIN_HTTPSERVER_H diff --git a/src/init.cpp b/src/init.cpp index 5272541722..a079dce5bc 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -11,24 +11,33 @@ #include "addrman.h" #include "amount.h" +#include "chain.h" +#include "chainparams.h" #include "checkpoints.h" #include "compat/sanity.h" +#include "consensus/validation.h" +#include "httpserver.h" +#include "httprpc.h" #include "key.h" #include "main.h" #include "miner.h" #include "net.h" +#include "policy/policy.h" #include "rpcserver.h" #include "script/standard.h" +#include "scheduler.h" #include "txdb.h" +#include "txmempool.h" #include "ui_interface.h" #include "util.h" #include "utilmoneystr.h" +#include "utilstrencodings.h" #include "validationinterface.h" #ifdef ENABLE_WALLET +#include "wallet/db.h" #include "wallet/wallet.h" #include "wallet/walletdb.h" #endif - #include <stdint.h> #include <stdio.h> @@ -38,11 +47,17 @@ #include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/replace.hpp> +#include <boost/bind.hpp> #include <boost/filesystem.hpp> +#include <boost/function.hpp> #include <boost/interprocess/sync/file_lock.hpp> #include <boost/thread.hpp> #include <openssl/crypto.h> +#if ENABLE_ZMQ +#include "zmq/zmqnotificationinterface.h" +#endif + using namespace std; #ifdef ENABLE_WALLET @@ -50,9 +65,13 @@ CWallet* pwalletMain = NULL; #endif bool fFeeEstimatesInitialized = false; +#if ENABLE_ZMQ +static CZMQNotificationInterface* pzmqNotificationInterface = NULL; +#endif + #ifdef WIN32 // Win32 LevelDB doesn't use filedescriptors, and the ones used for -// accessing block files, don't count towards to fd_set size limit +// accessing block files don't count towards the fd_set size limit // anyway. #define MIN_CORE_FILEDESCRIPTORS 0 #else @@ -134,6 +153,15 @@ public: static CCoinsViewDB *pcoinsdbview = NULL; static CCoinsViewErrorCatcher *pcoinscatcher = NULL; +void Interrupt(boost::thread_group& threadGroup) +{ + InterruptHTTPServer(); + InterruptHTTPRPC(); + InterruptRPC(); + InterruptREST(); + threadGroup.interrupt_all(); +} + void Shutdown() { LogPrintf("%s: In progress...\n", __func__); @@ -148,12 +176,16 @@ void Shutdown() /// module was initialized. RenameThread("bitcoin-shutoff"); mempool.AddTransactionsUpdated(1); - StopRPCThreads(); + + StopHTTPRPC(); + StopREST(); + StopRPC(); + StopHTTPServer(); #ifdef ENABLE_WALLET if (pwalletMain) pwalletMain->Flush(false); - GenerateBitcoins(false, NULL, 0); #endif + GenerateBitcoins(false, 0, Params()); StopNode(); UnregisterNodeSignals(GetNodeSignals()); @@ -186,14 +218,29 @@ void Shutdown() if (pwalletMain) pwalletMain->Flush(true); #endif + +#if ENABLE_ZMQ + if (pzmqNotificationInterface) { + UnregisterValidationInterface(pzmqNotificationInterface); + pzmqNotificationInterface->Shutdown(); + delete pzmqNotificationInterface; + pzmqNotificationInterface = NULL; + } +#endif + #ifndef WIN32 - boost::filesystem::remove(GetPidFile()); + try { + boost::filesystem::remove(GetPidFile()); + } catch (const boost::filesystem::filesystem_error& e) { + LogPrintf("%s: Unable to remove pidfile: %s\n", __func__, e.what()); + } #endif UnregisterAllValidationInterfaces(); #ifdef ENABLE_WALLET delete pwalletMain; pwalletMain = NULL; #endif + ECC_Stop(); LogPrintf("%s: done\n", __func__); } @@ -251,10 +298,13 @@ void OnRPCPreCommand(const CRPCCommand& cmd) std::string HelpMessage(HelpMessageMode mode) { + const bool showDebug = GetBoolArg("-help-debug", false); // 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("-alerts", strprintf(_("Receive and display P2P network alerts (default: %u)"), DEFAULT_ALERTS)); strUsage += HelpMessageOpt("-alertnotify=<cmd>", _("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=<cmd>", _("Execute command when the best block changes (%s in cmd is replaced by block hash)")); strUsage += HelpMessageOpt("-checkblocks=<n>", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288)); @@ -262,7 +312,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf")); if (mode == HMM_BITCOIND) { -#if !defined(WIN32) +#ifndef WIN32 strUsage += HelpMessageOpt("-daemon", _("Run in the background as a daemon and accept commands")); #endif } @@ -271,17 +321,15 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file") + " " + _("on startup")); strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS)); strUsage += HelpMessageOpt("-par=<n>", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), - -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS)); + -GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS)); #ifndef WIN32 strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid")); #endif - strUsage += HelpMessageOpt("-prune=<n>", _("Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex.") + " " + - _("Warning: Reverting this setting requires re-downloading the entire blockchain.") + " " + - _("(default: 0 = disable pruning blocks,") + " " + - strprintf(_(">%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")); - -#if !defined(WIN32) + strUsage += HelpMessageOpt("-prune=<n>", 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")); +#ifndef WIN32 strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)")); #endif strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0)); @@ -298,7 +346,7 @@ strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current strUsage += HelpMessageOpt("-externalip=<ip>", _("Specify your own public address")); strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0)); strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect)")); - strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), 125)); + strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), DEFAULT_MAX_PEER_CONNECTIONS)); strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000)); strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000)); strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy")); @@ -311,7 +359,7 @@ strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current strUsage += HelpMessageOpt("-timeout=<n>", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT)); #ifdef USE_UPNP #if USE_UPNP - strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening)")); + strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening and no -proxy)")); #else strUsage += HelpMessageOpt("-upnp", strprintf(_("Use UPnP to map the listening port (default: %u)"), 0)); #endif @@ -319,76 +367,87 @@ strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current strUsage += HelpMessageOpt("-whitebind=<addr>", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6")); strUsage += HelpMessageOpt("-whitelist=<netmask>", _("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")); - #ifdef ENABLE_WALLET strUsage += HelpMessageGroup(_("Wallet options:")); strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), 100)); - if (GetBoolArg("-help-debug", false)) - strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"), - FormatMoney(CWallet::minTxFee.GetFeePerK()))); - strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK()))); + if (showDebug) + strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)", + CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-paytxfee=<amt>", 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)"), 0)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1)); - strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1)); - strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"), - FormatMoney(maxTxFee))); + strUsage += HelpMessageOpt("-txconfirmtarget=<n>", 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=<amt>", 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(maxTxFee))); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup")); strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat")); strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), true)); strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("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)")); - +#endif + +#if ENABLE_ZMQ + strUsage += HelpMessageGroup(_("ZeroMQ notification options:")); + strUsage += HelpMessageOpt("-zmqpubhashblock=<address>", _("Enable publish hash block in <address>")); + strUsage += HelpMessageOpt("-zmqpubhashtransaction=<address>", _("Enable publish hash transaction in <address>")); + strUsage += HelpMessageOpt("-zmqpubrawblock=<address>", _("Enable publish raw block in <address>")); + strUsage += HelpMessageOpt("-zmqpubrawtransaction=<address>", _("Enable publish raw transaction in <address>")); #endif strUsage += HelpMessageGroup(_("Debugging/Testing options:")); - if (GetBoolArg("-help-debug", false)) + if (showDebug) { - strUsage += HelpMessageOpt("-checkpoints", strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1)); - strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf(_("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)"), 100)); - strUsage += HelpMessageOpt("-disablesafemode", strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0)); - strUsage += HelpMessageOpt("-testsafemode", strprintf(_("Force safe mode (default: %u)"), 0)); - strUsage += HelpMessageOpt("-dropmessagestest=<n>", _("Randomly drop 1 of every <n> network messages")); - strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", _("Randomly fuzz 1 of every <n> network messages")); - strUsage += HelpMessageOpt("-flushwallet", strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1)); - strUsage += HelpMessageOpt("-stopafterblockimport", strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0)); + strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", 1)); + strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)", 100)); + strUsage += HelpMessageOpt("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", 0)); + strUsage += HelpMessageOpt("-testsafemode", strprintf("Force safe mode (default: %u)", 0)); + strUsage += HelpMessageOpt("-dropmessagestest=<n>", "Randomly drop 1 of every <n> network messages"); + strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", "Randomly fuzz 1 of every <n> network messages"); + strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", 1)); + strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0)); + strUsage += HelpMessageOpt("-limitancestorcount=<n>", strprintf("Do not accept transactions if number of in-mempool ancestors is <n> or more (default: %u)", DEFAULT_ANCESTOR_LIMIT)); + strUsage += HelpMessageOpt("-limitancestorsize=<n>", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds <n> kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT)); + strUsage += HelpMessageOpt("-limitdescendantcount=<n>", strprintf("Do not accept transactions if any ancestor would have <n> or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT)); + strUsage += HelpMessageOpt("-limitdescendantsize=<n>", strprintf("Do not accept transactions if any ancestor would have more than <n> kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT)); } - string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net, proxy, prune"; // Don't translate these and qt below + string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, mempoolrej, net, proxy, prune, http, libevent"; // Don't translate these and qt below if (mode == HMM_BITCOIN_QT) debugCategories += ", qt"; strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " + - _("If <category> is not supplied, output all debugging information.") + _("<category> can be:") + " " + debugCategories + "."); -#ifdef ENABLE_WALLET + _("If <category> is not supplied or if <category> = 1, output all debugging information.") + _("<category> can be:") + " " + debugCategories + "."); strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0)); strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1)); -#endif strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)")); strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), 0)); strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1)); - if (GetBoolArg("-help-debug", false)) + if (showDebug) { - strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)"), 15)); - strUsage += HelpMessageOpt("-relaypriority", strprintf(_("Require high priority for relaying free or low-fee transactions (default: %u)"), 1)); - strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf(_("Limit size of signature cache to <n> entries (default: %u)"), 50000)); + strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)", 15)); + strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", 1)); + strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit size of signature cache to <n> entries (default: %u)", 50000)); } - strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for relaying (default: %s)"), + CURRENCY_UNIT, FormatMoney(::minRelayTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file")); - if (GetBoolArg("-help-debug", false)) + if (showDebug) { - strUsage += HelpMessageOpt("-printpriority", strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0)); - strUsage += HelpMessageOpt("-privdb", strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1)); - strUsage += HelpMessageOpt("-regtest", _("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.") + " " + - _("In this mode -genproclimit controls how many blocks are generated immediately.")); + strUsage += HelpMessageOpt("-printpriority", strprintf("Log transaction priority and fee per kB when mining blocks (default: %u)", 0)); + strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", 1)); + strUsage += HelpMessageOpt("-regtest", "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."); } strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)")); strUsage += HelpMessageOpt("-testnet", _("Use the test network")); 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("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1)); strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY)); @@ -396,6 +455,8 @@ strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current strUsage += HelpMessageOpt("-blockminsize=<n>", strprintf(_("Set minimum block size in bytes (default: %u)"), 0)); strUsage += HelpMessageOpt("-blockmaxsize=<n>", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); strUsage += HelpMessageOpt("-blockprioritysize=<n>", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); + if (showDebug) + strUsage += HelpMessageOpt("-blockversion=<n>", strprintf("Override block version to test forking scenarios (default: %d)", (int)CBlock::CURRENT_VERSION)); strUsage += HelpMessageGroup(_("RPC server options:")); strUsage += HelpMessageOpt("-server", _("Accept command line and JSON-RPC commands")); @@ -405,26 +466,26 @@ strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332)); strUsage += HelpMessageOpt("-rpcallowip=<ip>", _("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")); - strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4)); - strUsage += HelpMessageOpt("-rpckeepalive", strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1)); - - strUsage += HelpMessageGroup(_("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)")); - strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections")); - strUsage += HelpMessageOpt("-rpcsslcertificatechainfile=<file.cert>", strprintf(_("Server certificate file (default: %s)"), "server.cert")); - strUsage += HelpMessageOpt("-rpcsslprivatekeyfile=<file.pem>", strprintf(_("Server private key (default: %s)"), "server.pem")); - strUsage += HelpMessageOpt("-rpcsslciphers=<ciphers>", strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH")); + strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), DEFAULT_HTTP_THREADS)); + if (showDebug) { + strUsage += HelpMessageOpt("-rpcworkqueue=<n>", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE)); + strUsage += HelpMessageOpt("-rpcservertimeout=<n>", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT)); + } if (mode == HMM_BITCOIN_QT) { strUsage += HelpMessageGroup(_("UI Options:")); - if (GetBoolArg("-help-debug", false)) { - strUsage += HelpMessageOpt("-allowselfsignedrootcertificates", _("Allow self signed root certificates (default: 0)")); + if (showDebug) { + strUsage += HelpMessageOpt("-allowselfsignedrootcertificates", "Allow self signed root certificates (default: 0)"); } strUsage += HelpMessageOpt("-choosedatadir", _("Choose data directory on startup (default: 0)")); strUsage += HelpMessageOpt("-lang=<lang>", _("Set language, for example \"de_DE\" (default: system locale)")); strUsage += HelpMessageOpt("-min", _("Start minimized")); strUsage += HelpMessageOpt("-rootcertificates=<file>", _("Set SSL root certificates for payment request (default: -system-)")); strUsage += HelpMessageOpt("-splash", _("Show splash screen on startup (default: 1)")); + if (showDebug) { + strUsage += HelpMessageOpt("-uiplatform", "Select platform to customize UI for (one of windows, macosx, other; default: platform compiled on)"); + } } return strUsage; @@ -466,24 +527,43 @@ struct CImportingNow // If we're using -prune with -reindex, then delete block files that will be ignored by the // reindex. Since reindexing works by starting at block file 0 and looping until a blockfile -// is missing, and since pruning works by deleting the oldest block file first, just check -// for block file 0, and if it doesn't exist, delete all the block files in the -// directory (since they won't be read by the reindex but will take up disk space). -void DeleteAllBlockFiles() +// is missing, do the same here to delete any later block files after a gap. Also delete all +// rev files since they'll be rewritten by the reindex anyway. This ensures that vinfoBlockFile +// is in sync with what's actually on disk by the time we start downloading, so that pruning +// works correctly. +void CleanupBlockRevFiles() { - if (boost::filesystem::exists(GetBlockPosFilename(CDiskBlockPos(0, 0), "blk"))) - return; + using namespace boost::filesystem; + map<string, path> mapBlockFiles; + + // Glob all blk?????.dat and rev?????.dat files from the blocks directory. + // Remove the rev files immediately and insert the blk file paths into an + // ordered map keyed by block file index. + LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n"); + path blocksdir = GetDataDir() / "blocks"; + for (directory_iterator it(blocksdir); it != directory_iterator(); it++) { + if (is_regular_file(*it) && + it->path().filename().string().length() == 12 && + it->path().filename().string().substr(8,4) == ".dat") + { + if (it->path().filename().string().substr(0,3) == "blk") + mapBlockFiles[it->path().filename().string().substr(3,5)] = it->path(); + else if (it->path().filename().string().substr(0,3) == "rev") + remove(it->path()); + } + } - LogPrintf("Removing all blk?????.dat and rev?????.dat files for -reindex with -prune\n"); - boost::filesystem::path blocksdir = GetDataDir() / "blocks"; - for (boost::filesystem::directory_iterator it(blocksdir); it != boost::filesystem::directory_iterator(); it++) { - if (is_regular_file(*it)) { - if ((it->path().filename().string().length() == 12) && - (it->path().filename().string().substr(8,4) == ".dat") && - ((it->path().filename().string().substr(0,3) == "blk") || - (it->path().filename().string().substr(0,3) == "rev"))) - boost::filesystem::remove(it->path()); + // Remove all block files that aren't part of a contiguous set starting at + // zero by walking the ordered map (keys are block file indices) by + // keeping a separate counter. Once we hit a gap (or if 0 doesn't exist) + // start removing block files. + int nContigCounter = 0; + BOOST_FOREACH(const PAIRTYPE(string, path)& item, mapBlockFiles) { + if (atoi(item.first) == nContigCounter) { + nContigCounter++; + continue; } + remove(item.second); } } @@ -528,7 +608,7 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles) } // -loadblock= - BOOST_FOREACH(boost::filesystem::path &path, vImportFiles) { + BOOST_FOREACH(const boost::filesystem::path& path, vImportFiles) { FILE *file = fopen(path.string().c_str(), "rb"); if (file) { CImportingNow imp; @@ -562,10 +642,27 @@ bool InitSanityCheck(void) return true; } +bool AppInitServers(boost::thread_group& threadGroup) +{ + RPCServer::OnStopped(&OnRPCStopped); + RPCServer::OnPreCommand(&OnRPCPreCommand); + if (!InitHTTPServer()) + return false; + if (!StartRPC()) + return false; + if (!StartHTTPRPC()) + return false; + if (GetBoolArg("-rest", false) && !StartREST()) + return false; + if (!StartHTTPServer(threadGroup)) + return false; + return true; +} + /** Initialize bitcoin. * @pre Parameters should be parsed and config file should be read. */ -bool AppInit2(boost::thread_group& threadGroup) +bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) { // ********************************************************* Step 1: setup #ifdef _MSC_VER @@ -589,17 +686,12 @@ bool AppInit2(boost::thread_group& threadGroup) typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD); PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy"); if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE); - - // Initialize Windows Sockets - WSADATA wsadata; - int ret = WSAStartup(MAKEWORD(2,2), &wsadata); - if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2) - { - return InitError(strprintf("Error: Winsock library failed to start (WSAStartup returned error %d)", ret)); - } #endif -#ifndef WIN32 + if (!SetupNetworking()) + return InitError("Error: Initializing networking failed"); + +#ifndef WIN32 if (GetBoolArg("-sysperms", false)) { #ifdef ENABLE_WALLET if (!GetBoolArg("-disablewallet", false)) @@ -624,11 +716,9 @@ bool AppInit2(boost::thread_group& threadGroup) sa_hup.sa_flags = 0; sigaction(SIGHUP, &sa_hup, NULL); -#if defined (__SVR4) && defined (__sun) - // ignore SIGPIPE on Solaris + // Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly signal(SIGPIPE, SIG_IGN); #endif -#endif // ********************************************************* Step 2: parameter interactions const CChainParams& chainparams = Params(); @@ -638,6 +728,9 @@ bool AppInit2(boost::thread_group& threadGroup) fLogTimestamps = GetBoolArg("-logtimestamps", true); fLogIPs = GetBoolArg("-logips", false); + 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); + // when specifying an explicit binding address, you want to listen on it // even when -connect or -proxy is specified if (mapArgs.count("-bind")) { @@ -661,6 +754,10 @@ bool AppInit2(boost::thread_group& threadGroup) // to protect privacy, do not listen by default if a default proxy server is specified if (SoftSetBoolArg("-listen", false)) LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__); + // to protect privacy, do not use UPNP when a proxy is set. The user may still specify -listen=1 + // to listen locally, so don't rely on this happening through -listen below. + if (SoftSetBoolArg("-upnp", false)) + LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__); // to protect privacy, do not discover addresses by default if (SoftSetBoolArg("-discover", false)) LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__); @@ -692,30 +789,31 @@ bool AppInit2(boost::thread_group& threadGroup) LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__); } - // Make sure enough file descriptors are available - int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1); - nMaxConnections = GetArg("-maxconnections", 125); - nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0); - int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS); - if (nFD < MIN_CORE_FILEDESCRIPTORS) - return InitError(_("Not enough file descriptors available.")); - if (nFD - MIN_CORE_FILEDESCRIPTORS < nMaxConnections) - nMaxConnections = nFD - MIN_CORE_FILEDESCRIPTORS; - // if using block pruning, then disable txindex - // also disable the wallet (for now, until SPV support is implemented in wallet) if (GetArg("-prune", 0)) { if (GetBoolArg("-txindex", false)) return InitError(_("Prune mode is incompatible with -txindex.")); #ifdef ENABLE_WALLET - if (!GetBoolArg("-disablewallet", false)) { - if (SoftSetBoolArg("-disablewallet", true)) - LogPrintf("%s : parameter interaction: -prune -> setting -disablewallet=1\n", __func__); - else - return InitError(_("Can't run with a wallet in prune mode.")); + if (GetBoolArg("-rescan", false)) { + return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.")); } #endif } + + // Make sure enough file descriptors are available + int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1); + int nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); + nMaxConnections = std::max(nUserMaxConnections, 0); + + // Trim requested connection counts, to fit into system limitations + nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0); + int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS); + if (nFD < MIN_CORE_FILEDESCRIPTORS) + return InitError(_("Not enough file descriptors available.")); + nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS, nMaxConnections); + + if (nMaxConnections < nUserMaxConnections) + InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, because of system limitations."), nUserMaxConnections, nMaxConnections)); // ********************************************************* Step 3: parameter-to-internal-flags @@ -741,12 +839,12 @@ bool AppInit2(boost::thread_group& threadGroup) // Checkmempool and checkblockindex default to true in regtest mode mempool.setSanityCheck(GetBoolArg("-checkmempool", chainparams.DefaultConsistencyChecks())); fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks()); - Checkpoints::fEnabled = GetBoolArg("-checkpoints", true); + fCheckpointsEnabled = GetBoolArg("-checkpoints", true); // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS); if (nScriptCheckThreads <= 0) - nScriptCheckThreads += boost::thread::hardware_concurrency(); + nScriptCheckThreads += GetNumCores(); if (nScriptCheckThreads <= 1) nScriptCheckThreads = 0; else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS) @@ -754,7 +852,7 @@ bool AppInit2(boost::thread_group& threadGroup) fServer = GetBoolArg("-server", false); - // block pruning; get the amount of disk space (in MB) to allot for block & undo files + // block pruning; get the amount of disk space (in MiB) to allot for block & undo files int64_t nSignedPruneTarget = GetArg("-prune", 0) * 1024 * 1024; if (nSignedPruneTarget < 0) { return InitError(_("Prune cannot be configured with a negative value.")); @@ -762,7 +860,7 @@ bool AppInit2(boost::thread_group& threadGroup) nPruneTarget = (uint64_t) nSignedPruneTarget; if (nPruneTarget) { if (nPruneTarget < MIN_DISK_SPACE_FOR_BLOCK_FILES) { - return InitError(strprintf(_("Prune configured below the minimum of %d MB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024)); + return InitError(strprintf(_("Prune configured below the minimum of %d MiB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024)); } LogPrintf("Prune configured to target %uMiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024); fPruneMode = true; @@ -776,12 +874,6 @@ bool AppInit2(boost::thread_group& threadGroup) if (nConnectTimeout <= 0) nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; - // Continue to put "/P2SH/" in the coinbase to monitor - // BIP16 support. - // This can be removed eventually... - const char* pszP2SH = "/P2SH/"; - COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH)); - // Fee-per-kilobyte amount considered the same as "free" // If you are mining, be careful setting this: // if you set it to zero then @@ -797,6 +889,10 @@ bool AppInit2(boost::thread_group& threadGroup) return InitError(strprintf(_("Invalid amount for -minrelaytxfee=<amount>: '%s'"), mapArgs["-minrelaytxfee"])); } + fRequireStandard = !GetBoolArg("-acceptnonstdtxn", !Params().RequireStandard()); + if (Params().RequireStandard() && !fRequireStandard) + return InitError(strprintf("acceptnonstdtxn is not currently supported for %s chain", chainparams.NetworkIDString())); + #ifdef ENABLE_WALLET if (mapArgs.count("-mintxfee")) { @@ -834,18 +930,29 @@ bool AppInit2(boost::thread_group& threadGroup) mapArgs["-maxtxfee"], ::minRelayTxFee.ToString())); } } - nTxConfirmTarget = GetArg("-txconfirmtarget", 1); - bSpendZeroConfChange = GetArg("-spendzeroconfchange", true); - fSendFreeTransactions = GetArg("-sendfreetransactions", false); + nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); + bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", true); + fSendFreeTransactions = GetBoolArg("-sendfreetransactions", false); std::string strWalletFile = GetArg("-wallet", "wallet.dat"); #endif // ENABLE_WALLET - fIsBareMultisigStd = GetArg("-permitbaremultisig", true) != 0; + fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", true); 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 + + if (GetBoolArg("-peerbloomfilters", true)) + nLocalServices |= NODE_BLOOM; + // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log + // Initialize elliptic curve code + ECC_Start(); + // Sanity check if (!InitSanityCheck()) return InitError(_("Initialization sanity check failed. Bitcoin Core is shutting down.")); @@ -860,16 +967,24 @@ bool AppInit2(boost::thread_group& threadGroup) boost::filesystem::path pathLockFile = GetDataDir() / ".lock"; FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist. if (file) fclose(file); - 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)); + + 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)); + } 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())); + } + #ifndef WIN32 CreatePidFile(GetPidFile(), getpid()); #endif if (GetBoolArg("-shrinkdebugfile", !fDebug)) ShrinkDebugFile(); - 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); + + if (fPrintToDebugLog) + OpenDebugLog(); + LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); #ifdef ENABLE_WALLET LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0)); @@ -888,6 +1003,10 @@ bool AppInit2(boost::thread_group& threadGroup) threadGroup.create_thread(&ThreadScriptCheck); } + // Start the lightweight task scheduler thread + CScheduler::Function serviceLoop = boost::bind(&CScheduler::serviceQueue, &scheduler); + threadGroup.create_thread(boost::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop)); + /* Start the RPC server already. It will be started in "warmup" mode * and not really process calls already (but it will signify connections * that the server is there and will be ready later). Warmup mode will @@ -896,9 +1015,8 @@ bool AppInit2(boost::thread_group& threadGroup) if (fServer) { uiInterface.InitMessage.connect(SetRPCWarmupStatus); - RPCServer::OnStopped(&OnRPCStopped); - RPCServer::OnPreCommand(&OnRPCPreCommand); - StartRPCThreads(); + if (!AppInitServers(threadGroup)) + return InitError(_("Unable to start HTTP server. See debug log for details.")); } int64_t nStart; @@ -911,24 +1029,38 @@ bool AppInit2(boost::thread_group& threadGroup) std::string warningString; std::string errorString; - + if (!CWallet::Verify(strWalletFile, warningString, errorString)) return false; - + if (!warningString.empty()) InitWarning(warningString); if (!errorString.empty()) - return InitError(warningString); - + return InitError(errorString); + } // (!fDisableWallet) #endif // ENABLE_WALLET // ********************************************************* Step 6: network initialization RegisterNodeSignals(GetNodeSignals()); + // sanitize comments per BIP-0014, format user agent and check total size + std::vector<string> uacomments; + BOOST_FOREACH(string cmt, mapMultiArgs["-uacomment"]) + { + if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) + return InitError(strprintf("User Agent comment (%s) contains unsafe characters.", cmt)); + uacomments.push_back(SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)); + } + strSubVersion = FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments); + if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) { + return InitError(strprintf("Total length of network version string %i exceeds maximum of %i characters. Reduce the number and/or size of uacomments.", + strSubVersion.size(), MAX_SUBVERSION_LENGTH)); + } + if (mapArgs.count("-onlynet")) { std::set<enum Network> nets; - BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) { + BOOST_FOREACH(const std::string& snet, mapMultiArgs["-onlynet"]) { enum Network net = ParseNetwork(snet); if (net == NET_UNROUTABLE) return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet)); @@ -950,31 +1082,36 @@ bool AppInit2(boost::thread_group& threadGroup) } } - proxyType addrProxy; - bool fProxy = false; - if (mapArgs.count("-proxy")) { - addrProxy = proxyType(CService(mapArgs["-proxy"], 9050), GetArg("-proxyrandomize", true)); + bool proxyRandomize = GetBoolArg("-proxyrandomize", true); + // -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", ""); + if (proxyArg != "" && proxyArg != "0") { + proxyType addrProxy = proxyType(CService(proxyArg, 9050), proxyRandomize); if (!addrProxy.IsValid()) - return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"])); + return InitError(strprintf(_("Invalid -proxy address: '%s'"), proxyArg)); SetProxy(NET_IPV4, addrProxy); SetProxy(NET_IPV6, addrProxy); + SetProxy(NET_TOR, addrProxy); SetNameProxy(addrProxy); - fProxy = true; + SetReachable(NET_TOR); // by default, -proxy sets onion as reachable, unless -noonion later } - // -onion can override normal proxy, -noonion disables connecting to .onion entirely - if (!(mapArgs.count("-onion") && mapArgs["-onion"] == "0") && - (fProxy || mapArgs.count("-onion"))) { - proxyType addrOnion; - if (!mapArgs.count("-onion")) - addrOnion = addrProxy; - else - addrOnion = proxyType(CService(mapArgs["-onion"], 9050), GetArg("-proxyrandomize", true)); - if (!addrOnion.IsValid()) - return InitError(strprintf(_("Invalid -onion address: '%s'"), mapArgs["-onion"])); - SetProxy(NET_TOR, addrOnion); - SetReachable(NET_TOR); + // -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses + // -noonion (or -onion=0) disables connecting to .onion entirely + // An empty string is used to not override the onion proxy (in which case it defaults to -proxy set above, or none) + std::string onionArg = GetArg("-onion", ""); + if (onionArg != "") { + if (onionArg == "0") { // Handle -noonion/-onion=0 + SetReachable(NET_TOR, false); // 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); + } } // see Step 2: parameter interactions for more information about these @@ -985,13 +1122,13 @@ bool AppInit2(boost::thread_group& threadGroup) bool fBound = false; if (fListen) { if (mapArgs.count("-bind") || mapArgs.count("-whitebind")) { - BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) { + 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)); fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR)); } - BOOST_FOREACH(std::string strBind, mapMultiArgs["-whitebind"]) { + 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)); @@ -1011,7 +1148,7 @@ bool AppInit2(boost::thread_group& threadGroup) } if (mapArgs.count("-externalip")) { - BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) { + 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)); @@ -1019,9 +1156,18 @@ bool AppInit2(boost::thread_group& threadGroup) } } - BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"]) + BOOST_FOREACH(const std::string& strDest, mapMultiArgs["-seednode"]) AddOneShot(strDest); +#if ENABLE_ZMQ + pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs); + + if (pzmqNotificationInterface) { + pzmqNotificationInterface->Initialize(); + RegisterValidationInterface(pzmqNotificationInterface); + } +#endif + // ********************************************************* Step 7: load block chain fReindex = GetBoolArg("-reindex", false); @@ -1054,18 +1200,20 @@ bool AppInit2(boost::thread_group& threadGroup) } // cache size calculations - size_t nTotalCache = (GetArg("-dbcache", nDefaultDbCache) << 20); - if (nTotalCache < (nMinDbCache << 20)) - nTotalCache = (nMinDbCache << 20); // total cache cannot be less than nMinDbCache - else if (nTotalCache > (nMaxDbCache << 20)) - nTotalCache = (nMaxDbCache << 20); // total cache cannot be greater than nMaxDbCache - size_t nBlockTreeDBCache = nTotalCache / 8; + 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 + int64_t nBlockTreeDBCache = nTotalCache / 8; if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", false)) nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB nTotalCache -= nBlockTreeDBCache; - size_t nCoinDBCache = nTotalCache / 2; // use half of the remaining cache for coindb cache + int64_t nCoinDBCache = std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23)); // use 25%-50% of the remainder for disk cache nTotalCache -= nCoinDBCache; - nCoinCacheSize = nTotalCache / 300; // coins in memory require around 300 bytes + nCoinCacheUsage = nTotalCache; // the rest goes to in-memory cache + LogPrintf("Cache configuration:\n"); + LogPrintf("* Using %.1fMiB for block index database\n", nBlockTreeDBCache * (1.0 / 1024 / 1024)); + LogPrintf("* Using %.1fMiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024)); + LogPrintf("* Using %.1fMiB for in-memory UTXO set\n", nCoinCacheUsage * (1.0 / 1024 / 1024)); bool fLoaded = false; while (!fLoaded) { @@ -1090,9 +1238,9 @@ bool AppInit2(boost::thread_group& threadGroup) if (fReindex) { pblocktree->WriteReindexing(true); - //If we're reindexing in prune mode, wipe away all our block and undo data files + //If we're reindexing in prune mode, wipe away unusable block files and all undo data files if (fPruneMode) - DeleteAllBlockFiles(); + CleanupBlockRevFiles(); } if (!LoadBlockIndex()) { @@ -1129,6 +1277,18 @@ bool AppInit2(boost::thread_group& threadGroup) LogPrintf("Prune: pruned datadir may not have more than %d blocks; -checkblocks=%d may fail\n", MIN_BLOCKS_TO_KEEP, GetArg("-checkblocks", 288)); } + + { + LOCK(cs_main); + CBlockIndex* tip = chainActive.Tip(); + if (tip && tip->nTime > GetAdjustedTime() + 2 * 60 * 60) { + strLoadError = _("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"); + break; + } + } + if (!CVerifyDB().VerifyDB(pcoinsdbview, GetArg("-checklevel", 3), GetArg("-checkblocks", 288))) { strLoadError = _("Corrupted block database detected"); @@ -1179,15 +1339,6 @@ bool AppInit2(boost::thread_group& threadGroup) mempool.ReadFeeEstimates(est_filein); fFeeEstimatesInitialized = true; - // if prune mode, unset NODE_NETWORK and prune block files - if (fPruneMode) { - LogPrintf("Unsetting NODE_NETWORK on prune mode\n"); - nLocalServices &= ~NODE_NETWORK; - if (!fReindex) { - PruneAndFlush(); - } - } - // ********************************************************* Step 8: load wallet #ifdef ENABLE_WALLET if (fDisableWallet) { @@ -1290,6 +1441,19 @@ bool AppInit2(boost::thread_group& threadGroup) } 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(); @@ -1326,13 +1490,28 @@ bool AppInit2(boost::thread_group& threadGroup) pwalletMain->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", true)); } // (!fDisableWallet) #else // ENABLE_WALLET - LogPrintf("No wallet compiled in!\n"); + LogPrintf("No wallet support compiled in!\n"); #endif // !ENABLE_WALLET - // ********************************************************* Step 9: import blocks + + // ********************************************************* Step 9: data directory maintenance + + // if pruning, unset the service bit and perform the initial blockstore prune + // after any wallet rescanning has taken place. + if (fPruneMode) { + uiInterface.InitMessage(_("Pruning blockstore...")); + LogPrintf("Unsetting NODE_NETWORK on prune mode\n"); + nLocalServices &= ~NODE_NETWORK; + if (!fReindex) { + PruneAndFlush(); + } + } + + // ********************************************************* Step 10: import blocks 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)) @@ -1341,7 +1520,7 @@ bool AppInit2(boost::thread_group& threadGroup) std::vector<boost::filesystem::path> vImportFiles; if (mapArgs.count("-loadblock")) { - BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"]) + BOOST_FOREACH(const std::string& strFile, mapMultiArgs["-loadblock"]) vImportFiles.push_back(strFile); } threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles)); @@ -1351,7 +1530,7 @@ bool AppInit2(boost::thread_group& threadGroup) MilliSleep(10); } - // ********************************************************* Step 10: start node + // ********************************************************* Step 11: start node if (!CheckDiskSpace()) return false; @@ -1370,15 +1549,18 @@ bool AppInit2(boost::thread_group& threadGroup) LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0); #endif - StartNode(threadGroup); + 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); -#ifdef ENABLE_WALLET // Generate coins in the background - if (pwalletMain) - GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1)); -#endif + GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1), Params()); - // ********************************************************* Step 11: finished + // ********************************************************* Step 12: finished SetRPCWarmupFinished(); uiInterface.InitMessage(_("Done loading")); diff --git a/src/init.h b/src/init.h index d451f65be9..8cd51b0286 100644 --- a/src/init.h +++ b/src/init.h @@ -8,6 +8,7 @@ #include <string> +class CScheduler; class CWallet; namespace boost @@ -19,8 +20,10 @@ extern CWallet* pwalletMain; void StartShutdown(); bool ShutdownRequested(); +/** Interrupt threads */ +void Interrupt(boost::thread_group& threadGroup); void Shutdown(); -bool AppInit2(boost::thread_group& threadGroup); +bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler); /** The help message mode determines what help message to show */ enum HelpMessageMode { diff --git a/src/json/LICENSE.txt b/src/json/LICENSE.txt deleted file mode 100644 index 797d5363b3..0000000000 --- a/src/json/LICENSE.txt +++ /dev/null @@ -1,24 +0,0 @@ -The MIT License - -Copyright (c) 2007 - 2009 John W. Wilkinson - -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/src/json/json_spirit.h b/src/json/json_spirit.h deleted file mode 100644 index ac1879d5b3..0000000000 --- a/src/json/json_spirit.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef JSON_SPIRIT -#define JSON_SPIRIT - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_value.h" -#include "json_spirit_reader.h" -#include "json_spirit_writer.h" -#include "json_spirit_utils.h" - -#endif diff --git a/src/json/json_spirit_error_position.h b/src/json/json_spirit_error_position.h deleted file mode 100644 index 17208507df..0000000000 --- a/src/json/json_spirit_error_position.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef JSON_SPIRIT_ERROR_POSITION -#define JSON_SPIRIT_ERROR_POSITION - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include <string> - -namespace json_spirit -{ - // An Error_position exception is thrown by the "read_or_throw" functions below on finding an error. - // Note the "read_or_throw" functions are around 3 times slower than the standard functions "read" - // functions that return a bool. - // - struct Error_position - { - Error_position(); - Error_position( unsigned int line, unsigned int column, const std::string& reason ); - bool operator==( const Error_position& lhs ) const; - unsigned int line_; - unsigned int column_; - std::string reason_; - }; - - inline Error_position::Error_position() - : line_( 0 ) - , column_( 0 ) - { - } - - inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason ) - : line_( line ) - , column_( column ) - , reason_( reason ) - { - } - - inline bool Error_position::operator==( const Error_position& lhs ) const - { - if( this == &lhs ) return true; - - return ( reason_ == lhs.reason_ ) && - ( line_ == lhs.line_ ) && - ( column_ == lhs.column_ ); -} -} - -#endif diff --git a/src/json/json_spirit_reader.cpp b/src/json/json_spirit_reader.cpp deleted file mode 100644 index aa4f637226..0000000000 --- a/src/json/json_spirit_reader.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#include "json_spirit_reader.h" -#include "json_spirit_reader_template.h" - -using namespace json_spirit; - -bool json_spirit::read( const std::string& s, Value& value ) -{ - return read_string( s, value ); -} - -void json_spirit::read_or_throw( const std::string& s, Value& value ) -{ - read_string_or_throw( s, value ); -} - -bool json_spirit::read( std::istream& is, Value& value ) -{ - return read_stream( is, value ); -} - -void json_spirit::read_or_throw( std::istream& is, Value& value ) -{ - read_stream_or_throw( is, value ); -} - -bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) -{ - return read_range( begin, end, value ); -} - -void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) -{ - begin = read_range_or_throw( begin, end, value ); -} - -#ifndef BOOST_NO_STD_WSTRING - -bool json_spirit::read( const std::wstring& s, wValue& value ) -{ - return read_string( s, value ); -} - -void json_spirit::read_or_throw( const std::wstring& s, wValue& value ) -{ - read_string_or_throw( s, value ); -} - -bool json_spirit::read( std::wistream& is, wValue& value ) -{ - return read_stream( is, value ); -} - -void json_spirit::read_or_throw( std::wistream& is, wValue& value ) -{ - read_stream_or_throw( is, value ); -} - -bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) -{ - return read_range( begin, end, value ); -} - -void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) -{ - begin = read_range_or_throw( begin, end, value ); -} - -#endif - -bool json_spirit::read( const std::string& s, mValue& value ) -{ - return read_string( s, value ); -} - -void json_spirit::read_or_throw( const std::string& s, mValue& value ) -{ - read_string_or_throw( s, value ); -} - -bool json_spirit::read( std::istream& is, mValue& value ) -{ - return read_stream( is, value ); -} - -void json_spirit::read_or_throw( std::istream& is, mValue& value ) -{ - read_stream_or_throw( is, value ); -} - -bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) -{ - return read_range( begin, end, value ); -} - -void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) -{ - begin = read_range_or_throw( begin, end, value ); -} - -#ifndef BOOST_NO_STD_WSTRING - -bool json_spirit::read( const std::wstring& s, wmValue& value ) -{ - return read_string( s, value ); -} - -void json_spirit::read_or_throw( const std::wstring& s, wmValue& value ) -{ - read_string_or_throw( s, value ); -} - -bool json_spirit::read( std::wistream& is, wmValue& value ) -{ - return read_stream( is, value ); -} - -void json_spirit::read_or_throw( std::wistream& is, wmValue& value ) -{ - read_stream_or_throw( is, value ); -} - -bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) -{ - return read_range( begin, end, value ); -} - -void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) -{ - begin = read_range_or_throw( begin, end, value ); -} - -#endif diff --git a/src/json/json_spirit_reader.h b/src/json/json_spirit_reader.h deleted file mode 100644 index 96494a9789..0000000000 --- a/src/json/json_spirit_reader.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef JSON_SPIRIT_READER -#define JSON_SPIRIT_READER - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_value.h" -#include "json_spirit_error_position.h" -#include <iostream> - -namespace json_spirit -{ - // functions to reads a JSON values - - bool read( const std::string& s, Value& value ); - bool read( std::istream& is, Value& value ); - bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); - - void read_or_throw( const std::string& s, Value& value ); - void read_or_throw( std::istream& is, Value& value ); - void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); - -#ifndef BOOST_NO_STD_WSTRING - - bool read( const std::wstring& s, wValue& value ); - bool read( std::wistream& is, wValue& value ); - bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); - - void read_or_throw( const std::wstring& s, wValue& value ); - void read_or_throw( std::wistream& is, wValue& value ); - void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); - -#endif - - bool read( const std::string& s, mValue& value ); - bool read( std::istream& is, mValue& value ); - bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); - - void read_or_throw( const std::string& s, mValue& value ); - void read_or_throw( std::istream& is, mValue& value ); - void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); - -#ifndef BOOST_NO_STD_WSTRING - - bool read( const std::wstring& s, wmValue& value ); - bool read( std::wistream& is, wmValue& value ); - bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); - - void read_or_throw( const std::wstring& s, wmValue& value ); - void read_or_throw( std::wistream& is, wmValue& value ); - void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); - -#endif -} - -#endif diff --git a/src/json/json_spirit_reader_template.h b/src/json/json_spirit_reader_template.h deleted file mode 100644 index 46f5892f62..0000000000 --- a/src/json/json_spirit_reader_template.h +++ /dev/null @@ -1,612 +0,0 @@ -#ifndef JSON_SPIRIT_READER_TEMPLATE -#define JSON_SPIRIT_READER_TEMPLATE - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#include "json_spirit_value.h" -#include "json_spirit_error_position.h" - -//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread - -#include <boost/bind.hpp> -#include <boost/function.hpp> -#include <boost/version.hpp> - -#if BOOST_VERSION >= 103800 - #include <boost/spirit/include/classic_core.hpp> - #include <boost/spirit/include/classic_confix.hpp> - #include <boost/spirit/include/classic_escape_char.hpp> - #include <boost/spirit/include/classic_multi_pass.hpp> - #include <boost/spirit/include/classic_position_iterator.hpp> - #define spirit_namespace boost::spirit::classic -#else - #include <boost/spirit/core.hpp> - #include <boost/spirit/utility/confix.hpp> - #include <boost/spirit/utility/escape_char.hpp> - #include <boost/spirit/iterator/multi_pass.hpp> - #include <boost/spirit/iterator/position_iterator.hpp> - #define spirit_namespace boost::spirit -#endif - -namespace json_spirit -{ - const spirit_namespace::int_parser < int64_t > int64_p = spirit_namespace::int_parser < int64_t >(); - const spirit_namespace::uint_parser< uint64_t > uint64_p = spirit_namespace::uint_parser< uint64_t >(); - - template< class Iter_type > - bool is_eq( Iter_type first, Iter_type last, const char* c_str ) - { - for( Iter_type i = first; i != last; ++i, ++c_str ) - { - if( *c_str == 0 ) return false; - - if( *i != *c_str ) return false; - } - - return true; - } - - template< class Char_type > - Char_type hex_to_num( const Char_type c ) - { - if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0'; - if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10; - if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10; - return 0; - } - - template< class Char_type, class Iter_type > - Char_type hex_str_to_char( Iter_type& begin ) - { - const Char_type c1( *( ++begin ) ); - const Char_type c2( *( ++begin ) ); - - return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 ); - } - - template< class Char_type, class Iter_type > - Char_type unicode_str_to_char( Iter_type& begin ) - { - const Char_type c1( *( ++begin ) ); - const Char_type c2( *( ++begin ) ); - const Char_type c3( *( ++begin ) ); - const Char_type c4( *( ++begin ) ); - - return ( hex_to_num( c1 ) << 12 ) + - ( hex_to_num( c2 ) << 8 ) + - ( hex_to_num( c3 ) << 4 ) + - hex_to_num( c4 ); - } - - template< class String_type > - void append_esc_char_and_incr_iter( String_type& s, - typename String_type::const_iterator& begin, - typename String_type::const_iterator end ) - { - typedef typename String_type::value_type Char_type; - - const Char_type c2( *begin ); - - switch( c2 ) - { - case 't': s += '\t'; break; - case 'b': s += '\b'; break; - case 'f': s += '\f'; break; - case 'n': s += '\n'; break; - case 'r': s += '\r'; break; - case '\\': s += '\\'; break; - case '/': s += '/'; break; - case '"': s += '"'; break; - case 'x': - { - if( end - begin >= 3 ) // expecting "xHH..." - { - s += hex_str_to_char< Char_type >( begin ); - } - break; - } - case 'u': - { - if( end - begin >= 5 ) // expecting "uHHHH..." - { - s += unicode_str_to_char< Char_type >( begin ); - } - break; - } - } - } - - template< class String_type > - String_type substitute_esc_chars( typename String_type::const_iterator begin, - typename String_type::const_iterator end ) - { - typedef typename String_type::const_iterator Iter_type; - - if( end - begin < 2 ) return String_type( begin, end ); - - String_type result; - - result.reserve( end - begin ); - - const Iter_type end_minus_1( end - 1 ); - - Iter_type substr_start = begin; - Iter_type i = begin; - - for( ; i < end_minus_1; ++i ) - { - if( *i == '\\' ) - { - result.append( substr_start, i ); - - ++i; // skip the '\' - - append_esc_char_and_incr_iter( result, i, end ); - - substr_start = i + 1; - } - } - - result.append( substr_start, end ); - - return result; - } - - template< class String_type > - String_type get_str_( typename String_type::const_iterator begin, - typename String_type::const_iterator end ) - { - assert( end - begin >= 2 ); - - typedef typename String_type::const_iterator Iter_type; - - Iter_type str_without_quotes( ++begin ); - Iter_type end_without_quotes( --end ); - - return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes ); - } - - inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end ) - { - return get_str_< std::string >( begin, end ); - } - - inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end ) - { - return get_str_< std::wstring >( begin, end ); - } - - template< class String_type, class Iter_type > - String_type get_str( Iter_type begin, Iter_type end ) - { - const String_type tmp( begin, end ); // convert multipass iterators to string iterators - - return get_str( tmp.begin(), tmp.end() ); - } - - // this class's methods get called by the spirit parse resulting - // in the creation of a JSON object or array - // - // NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator - // - template< class Value_type, class Iter_type > - class Semantic_actions - { - public: - - typedef typename Value_type::Config_type Config_type; - typedef typename Config_type::String_type String_type; - typedef typename Config_type::Object_type Object_type; - typedef typename Config_type::Array_type Array_type; - typedef typename String_type::value_type Char_type; - - Semantic_actions( Value_type& value ) - : value_( value ) - , current_p_( 0 ) - { - } - - void begin_obj( Char_type c ) - { - assert( c == '{' ); - - begin_compound< Object_type >(); - } - - void end_obj( Char_type c ) - { - assert( c == '}' ); - - end_compound(); - } - - void begin_array( Char_type c ) - { - assert( c == '[' ); - - begin_compound< Array_type >(); - } - - void end_array( Char_type c ) - { - assert( c == ']' ); - - end_compound(); - } - - void new_name( Iter_type begin, Iter_type end ) - { - assert( current_p_->type() == obj_type ); - - name_ = get_str< String_type >( begin, end ); - } - - void new_str( Iter_type begin, Iter_type end ) - { - add_to_current( get_str< String_type >( begin, end ) ); - } - - void new_true( Iter_type begin, Iter_type end ) - { - assert( is_eq( begin, end, "true" ) ); - - add_to_current( true ); - } - - void new_false( Iter_type begin, Iter_type end ) - { - assert( is_eq( begin, end, "false" ) ); - - add_to_current( false ); - } - - void new_null( Iter_type begin, Iter_type end ) - { - assert( is_eq( begin, end, "null" ) ); - - add_to_current( Value_type() ); - } - - void new_int( int64_t i ) - { - add_to_current( i ); - } - - void new_uint64( uint64_t ui ) - { - add_to_current( ui ); - } - - void new_real( double d ) - { - add_to_current( d ); - } - - private: - - Semantic_actions& operator=( const Semantic_actions& ); - // to prevent "assignment operator could not be generated" warning - - Value_type* add_first( const Value_type& value ) - { - assert( current_p_ == 0 ); - - value_ = value; - current_p_ = &value_; - return current_p_; - } - - template< class Array_or_obj > - void begin_compound() - { - if( current_p_ == 0 ) - { - add_first( Array_or_obj() ); - } - else - { - stack_.push_back( current_p_ ); - - Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place - - current_p_ = add_to_current( new_array_or_obj ); - } - } - - void end_compound() - { - if( current_p_ != &value_ ) - { - current_p_ = stack_.back(); - - stack_.pop_back(); - } - } - - Value_type* add_to_current( const Value_type& value ) - { - if( current_p_ == 0 ) - { - return add_first( value ); - } - else if( current_p_->type() == array_type ) - { - current_p_->get_array().push_back( value ); - - return ¤t_p_->get_array().back(); - } - - assert( current_p_->type() == obj_type ); - - return &Config_type::add( current_p_->get_obj(), name_, value ); - } - - Value_type& value_; // this is the object or array that is being created - Value_type* current_p_; // the child object or array that is currently being constructed - - std::vector< Value_type* > stack_; // previous child objects and arrays - - String_type name_; // of current name/value pair - }; - - template< typename Iter_type > - void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason ) - { - throw Error_position( i.get_position().line, i.get_position().column, reason ); - } - - template< typename Iter_type > - void throw_error( Iter_type i, const std::string& reason ) - { - throw reason; - } - - // the spirit grammer - // - template< class Value_type, class Iter_type > - class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > > - { - public: - - typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t; - - Json_grammer( Semantic_actions_t& semantic_actions ) - : actions_( semantic_actions ) - { - } - - static void throw_not_value( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not a value" ); - } - - static void throw_not_array( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not an array" ); - } - - static void throw_not_object( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not an object" ); - } - - static void throw_not_pair( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not a pair" ); - } - - static void throw_not_colon( Iter_type begin, Iter_type end ) - { - throw_error( begin, "no colon in pair" ); - } - - static void throw_not_string( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not a string" ); - } - - template< typename ScannerT > - class definition - { - public: - - definition( const Json_grammer& self ) - { - using namespace spirit_namespace; - - typedef typename Value_type::String_type::value_type Char_type; - - // first we convert the semantic action class methods to functors with the - // parameter signature expected by spirit - - typedef boost::function< void( Char_type ) > Char_action; - typedef boost::function< void( Iter_type, Iter_type ) > Str_action; - typedef boost::function< void( double ) > Real_action; - typedef boost::function< void( int64_t ) > Int_action; - typedef boost::function< void( uint64_t ) > Uint64_action; - - Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) ); - Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) ); - Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) ); - Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) ); - Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) ); - Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) ); - Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) ); - Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) ); - Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) ); - Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) ); - Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) ); - Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) ); - - // actual grammer - - json_ - = value_ | eps_p[ &throw_not_value ] - ; - - value_ - = string_[ new_str ] - | number_ - | object_ - | array_ - | str_p( "true" ) [ new_true ] - | str_p( "false" )[ new_false ] - | str_p( "null" ) [ new_null ] - ; - - object_ - = ch_p('{')[ begin_obj ] - >> !members_ - >> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] ) - ; - - members_ - = pair_ >> *( ',' >> pair_ ) - ; - - pair_ - = string_[ new_name ] - >> ( ':' | eps_p[ &throw_not_colon ] ) - >> ( value_ | eps_p[ &throw_not_value ] ) - ; - - array_ - = ch_p('[')[ begin_array ] - >> !elements_ - >> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] ) - ; - - elements_ - = value_ >> *( ',' >> value_ ) - ; - - string_ - = lexeme_d // this causes white space inside a string to be retained - [ - confix_p - ( - '"', - *lex_escape_ch_p, - '"' - ) - ] - ; - - number_ - = strict_real_p[ new_real ] - | int64_p [ new_int ] - | uint64_p [ new_uint64 ] - ; - } - - spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_; - - const spirit_namespace::rule< ScannerT >& start() const { return json_; } - }; - - private: - - Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning - - Semantic_actions_t& actions_; - }; - - template< class Iter_type, class Value_type > - Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) - { - Semantic_actions< Value_type, Iter_type > semantic_actions( value ); - - const spirit_namespace::parse_info< Iter_type > info = - spirit_namespace::parse( begin, end, - Json_grammer< Value_type, Iter_type >( semantic_actions ), - spirit_namespace::space_p ); - - if( !info.hit ) - { - assert( false ); // in theory exception should already have been thrown - throw_error( info.stop, "error" ); - } - - return info.stop; - } - - template< class Iter_type, class Value_type > - void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) - { - typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t; - - const Posn_iter_t posn_begin( begin, end ); - const Posn_iter_t posn_end( end, end ); - - read_range_or_throw( posn_begin, posn_end, value ); - } - - template< class Iter_type, class Value_type > - bool read_range( Iter_type& begin, Iter_type end, Value_type& value ) - { - try - { - begin = read_range_or_throw( begin, end, value ); - - return true; - } - catch( ... ) - { - return false; - } - } - - template< class String_type, class Value_type > - void read_string_or_throw( const String_type& s, Value_type& value ) - { - add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value ); - } - - template< class String_type, class Value_type > - bool read_string( const String_type& s, Value_type& value ) - { - typename String_type::const_iterator begin = s.begin(); - - return read_range( begin, s.end(), value ); - } - - template< class Istream_type > - struct Multi_pass_iters - { - typedef typename Istream_type::char_type Char_type; - typedef std::istream_iterator< Char_type, Char_type > istream_iter; - typedef spirit_namespace::multi_pass< istream_iter > Mp_iter; - - Multi_pass_iters( Istream_type& is ) - { - is.unsetf( std::ios::skipws ); - - begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) ); - end_ = spirit_namespace::make_multi_pass( istream_iter() ); - } - - Mp_iter begin_; - Mp_iter end_; - }; - - template< class Istream_type, class Value_type > - bool read_stream( Istream_type& is, Value_type& value ) - { - Multi_pass_iters< Istream_type > mp_iters( is ); - - return read_range( mp_iters.begin_, mp_iters.end_, value ); - } - - template< class Istream_type, class Value_type > - void read_stream_or_throw( Istream_type& is, Value_type& value ) - { - const Multi_pass_iters< Istream_type > mp_iters( is ); - - add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value ); - } -} - -#endif diff --git a/src/json/json_spirit_stream_reader.h b/src/json/json_spirit_stream_reader.h deleted file mode 100644 index 7e59c9adc2..0000000000 --- a/src/json/json_spirit_stream_reader.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef JSON_SPIRIT_READ_STREAM -#define JSON_SPIRIT_READ_STREAM - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_reader_template.h" - -namespace json_spirit -{ - // these classes allows you to read multiple top level contiguous values from a stream, - // the normal stream read functions have a bug that prevent multiple top level values - // from being read unless they are separated by spaces - - template< class Istream_type, class Value_type > - class Stream_reader - { - public: - - Stream_reader( Istream_type& is ) - : iters_( is ) - { - } - - bool read_next( Value_type& value ) - { - return read_range( iters_.begin_, iters_.end_, value ); - } - - private: - - typedef Multi_pass_iters< Istream_type > Mp_iters; - - Mp_iters iters_; - }; - - template< class Istream_type, class Value_type > - class Stream_reader_thrower - { - public: - - Stream_reader_thrower( Istream_type& is ) - : iters_( is ) - , posn_begin_( iters_.begin_, iters_.end_ ) - , posn_end_( iters_.end_, iters_.end_ ) - { - } - - void read_next( Value_type& value ) - { - posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value ); - } - - private: - - typedef Multi_pass_iters< Istream_type > Mp_iters; - typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t; - - Mp_iters iters_; - Posn_iter_t posn_begin_, posn_end_; - }; -} - -#endif diff --git a/src/json/json_spirit_utils.h b/src/json/json_spirit_utils.h deleted file mode 100644 index 553e3b96a4..0000000000 --- a/src/json/json_spirit_utils.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef JSON_SPIRIT_UTILS -#define JSON_SPIRIT_UTILS - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_value.h" -#include <map> - -namespace json_spirit -{ - template< class Obj_t, class Map_t > - void obj_to_map( const Obj_t& obj, Map_t& mp_obj ) - { - mp_obj.clear(); - - for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i ) - { - mp_obj[ i->name_ ] = i->value_; - } - } - - template< class Obj_t, class Map_t > - void map_to_obj( const Map_t& mp_obj, Obj_t& obj ) - { - obj.clear(); - - for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i ) - { - obj.push_back( typename Obj_t::value_type( i->first, i->second ) ); - } - } - - typedef std::map< std::string, Value > Mapped_obj; - -#ifndef BOOST_NO_STD_WSTRING - typedef std::map< std::wstring, wValue > wMapped_obj; -#endif - - template< class Object_type, class String_type > - const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name ) - { - for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i ) - { - if( i->name_ == name ) - { - return i->value_; - } - } - - return Object_type::value_type::Value_type::null; - } -} - -#endif diff --git a/src/json/json_spirit_value.cpp b/src/json/json_spirit_value.cpp deleted file mode 100644 index 44d2f06a01..0000000000 --- a/src/json/json_spirit_value.cpp +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright (c) 2007 John W Wilkinson - - This source code can be used for any purpose as long as - this comment is retained. */ - -// json spirit version 2.00 - -#include "json_spirit_value.h" diff --git a/src/json/json_spirit_value.h b/src/json/json_spirit_value.h deleted file mode 100644 index 13cc89210c..0000000000 --- a/src/json/json_spirit_value.h +++ /dev/null @@ -1,534 +0,0 @@ -#ifndef JSON_SPIRIT_VALUE -#define JSON_SPIRIT_VALUE - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include <vector> -#include <map> -#include <string> -#include <cassert> -#include <sstream> -#include <stdexcept> -#include <stdint.h> -#include <boost/config.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/variant.hpp> - -namespace json_spirit -{ - enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type }; - static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"}; - - template< class Config > // Config determines whether the value uses std::string or std::wstring and - // whether JSON Objects are represented as vectors or maps - class Value_impl - { - public: - - typedef Config Config_type; - typedef typename Config::String_type String_type; - typedef typename Config::Object_type Object; - typedef typename Config::Array_type Array; - typedef typename String_type::const_pointer Const_str_ptr; // eg const char* - - Value_impl(); // creates null value - Value_impl( Const_str_ptr value ); - Value_impl( const String_type& value ); - Value_impl( const Object& value ); - Value_impl( const Array& value ); - Value_impl( bool value ); - Value_impl( int value ); - Value_impl( int64_t value ); - Value_impl( uint64_t value ); - Value_impl( double value ); - - Value_impl( const Value_impl& other ); - - bool operator==( const Value_impl& lhs ) const; - - Value_impl& operator=( const Value_impl& lhs ); - - Value_type type() const; - - bool is_uint64() const; - bool is_null() const; - - const String_type& get_str() const; - const Object& get_obj() const; - const Array& get_array() const; - bool get_bool() const; - int get_int() const; - int64_t get_int64() const; - uint64_t get_uint64() const; - double get_real() const; - - Object& get_obj(); - Array& get_array(); - - template< typename T > T get_value() const; // example usage: int i = value.get_value< int >(); - // or double d = value.get_value< double >(); - - static const Value_impl null; - - private: - - void check_type( const Value_type vtype ) const; - - typedef boost::variant< String_type, - boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, - bool, int64_t, double > Variant; - - Value_type type_; - Variant v_; - bool is_uint64_; - }; - - // vector objects - - template< class Config > - struct Pair_impl - { - typedef typename Config::String_type String_type; - typedef typename Config::Value_type Value_type; - - Pair_impl( const String_type& name, const Value_type& value ); - - bool operator==( const Pair_impl& lhs ) const; - - String_type name_; - Value_type value_; - }; - - template< class String > - struct Config_vector - { - typedef String String_type; - typedef Value_impl< Config_vector > Value_type; - typedef Pair_impl < Config_vector > Pair_type; - typedef std::vector< Value_type > Array_type; - typedef std::vector< Pair_type > Object_type; - - static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) - { - obj.push_back( Pair_type( name , value ) ); - - return obj.back().value_; - } - - static String_type get_name( const Pair_type& pair ) - { - return pair.name_; - } - - static Value_type get_value( const Pair_type& pair ) - { - return pair.value_; - } - }; - - // typedefs for ASCII - - typedef Config_vector< std::string > Config; - - typedef Config::Value_type Value; - typedef Config::Pair_type Pair; - typedef Config::Object_type Object; - typedef Config::Array_type Array; - - // typedefs for Unicode - -#ifndef BOOST_NO_STD_WSTRING - - typedef Config_vector< std::wstring > wConfig; - - typedef wConfig::Value_type wValue; - typedef wConfig::Pair_type wPair; - typedef wConfig::Object_type wObject; - typedef wConfig::Array_type wArray; -#endif - - // map objects - - template< class String > - struct Config_map - { - typedef String String_type; - typedef Value_impl< Config_map > Value_type; - typedef std::vector< Value_type > Array_type; - typedef std::map< String_type, Value_type > Object_type; - typedef typename Object_type::value_type Pair_type; - - static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) - { - return obj[ name ] = value; - } - - static String_type get_name( const Pair_type& pair ) - { - return pair.first; - } - - static Value_type get_value( const Pair_type& pair ) - { - return pair.second; - } - }; - - // typedefs for ASCII - - typedef Config_map< std::string > mConfig; - - typedef mConfig::Value_type mValue; - typedef mConfig::Object_type mObject; - typedef mConfig::Array_type mArray; - - // typedefs for Unicode - -#ifndef BOOST_NO_STD_WSTRING - - typedef Config_map< std::wstring > wmConfig; - - typedef wmConfig::Value_type wmValue; - typedef wmConfig::Object_type wmObject; - typedef wmConfig::Array_type wmArray; - -#endif - - /////////////////////////////////////////////////////////////////////////////////////////////// - // - // implementation - - template< class Config > - const Value_impl< Config > Value_impl< Config >::null; - - template< class Config > - Value_impl< Config >::Value_impl() - : type_( null_type ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const Const_str_ptr value ) - : type_( str_type ) - , v_( String_type( value ) ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const String_type& value ) - : type_( str_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const Object& value ) - : type_( obj_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const Array& value ) - : type_( array_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( bool value ) - : type_( bool_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( int value ) - : type_( int_type ) - , v_( static_cast< int64_t >( value ) ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( int64_t value ) - : type_( int_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( uint64_t value ) - : type_( int_type ) - , v_( static_cast< int64_t >( value ) ) - , is_uint64_( true ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( double value ) - : type_( real_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const Value_impl< Config >& other ) - : type_( other.type() ) - , v_( other.v_ ) - , is_uint64_( other.is_uint64_ ) - { - } - - template< class Config > - Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs ) - { - Value_impl tmp( lhs ); - - std::swap( type_, tmp.type_ ); - std::swap( v_, tmp.v_ ); - std::swap( is_uint64_, tmp.is_uint64_ ); - - return *this; - } - - template< class Config > - bool Value_impl< Config >::operator==( const Value_impl& lhs ) const - { - if( this == &lhs ) return true; - - if( type() != lhs.type() ) return false; - - return v_ == lhs.v_; - } - - template< class Config > - Value_type Value_impl< Config >::type() const - { - return type_; - } - - template< class Config > - bool Value_impl< Config >::is_uint64() const - { - return is_uint64_; - } - - template< class Config > - bool Value_impl< Config >::is_null() const - { - return type() == null_type; - } - - template< class Config > - void Value_impl< Config >::check_type( const Value_type vtype ) const - { - if( type() != vtype ) - { - std::ostringstream os; - - ///// Bitcoin: Tell the types by name instead of by number - os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype]; - - throw std::runtime_error( os.str() ); - } - } - - template< class Config > - const typename Config::String_type& Value_impl< Config >::get_str() const - { - check_type( str_type ); - - return *boost::get< String_type >( &v_ ); - } - - template< class Config > - const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const - { - check_type( obj_type ); - - return *boost::get< Object >( &v_ ); - } - - template< class Config > - const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const - { - check_type( array_type ); - - return *boost::get< Array >( &v_ ); - } - - template< class Config > - bool Value_impl< Config >::get_bool() const - { - check_type( bool_type ); - - return boost::get< bool >( v_ ); - } - - template< class Config > - int Value_impl< Config >::get_int() const - { - check_type( int_type ); - - return static_cast< int >( get_int64() ); - } - - template< class Config > - int64_t Value_impl< Config >::get_int64() const - { - check_type( int_type ); - - return boost::get< int64_t >( v_ ); - } - - template< class Config > - uint64_t Value_impl< Config >::get_uint64() const - { - check_type( int_type ); - - return static_cast< uint64_t >( get_int64() ); - } - - template< class Config > - double Value_impl< Config >::get_real() const - { - if( type() == int_type ) - { - return is_uint64() ? static_cast< double >( get_uint64() ) - : static_cast< double >( get_int64() ); - } - - check_type( real_type ); - - return boost::get< double >( v_ ); - } - - template< class Config > - typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() - { - check_type( obj_type ); - - return *boost::get< Object >( &v_ ); - } - - template< class Config > - typename Value_impl< Config >::Array& Value_impl< Config >::get_array() - { - check_type( array_type ); - - return *boost::get< Array >( &v_ ); - } - - template< class Config > - Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value ) - : name_( name ) - , value_( value ) - { - } - - template< class Config > - bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const - { - if( this == &lhs ) return true; - - return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ ); - } - - // converts a C string, ie. 8 bit char array, to a string object - // - template < class String_type > - String_type to_str( const char* c_str ) - { - String_type result; - - for( const char* p = c_str; *p != 0; ++p ) - { - result += *p; - } - - return result; - } - - // - - namespace internal_ - { - template< typename T > - struct Type_to_type - { - }; - - template< class Value > - int get_value( const Value& value, Type_to_type< int > ) - { - return value.get_int(); - } - - template< class Value > - int64_t get_value( const Value& value, Type_to_type< int64_t > ) - { - return value.get_int64(); - } - - template< class Value > - uint64_t get_value( const Value& value, Type_to_type< uint64_t > ) - { - return value.get_uint64(); - } - - template< class Value > - double get_value( const Value& value, Type_to_type< double > ) - { - return value.get_real(); - } - - template< class Value > - typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > ) - { - return value.get_str(); - } - - template< class Value > - typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > ) - { - return value.get_array(); - } - - template< class Value > - typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > ) - { - return value.get_obj(); - } - - template< class Value > - bool get_value( const Value& value, Type_to_type< bool > ) - { - return value.get_bool(); - } - } - - template< class Config > - template< typename T > - T Value_impl< Config >::get_value() const - { - return internal_::get_value( *this, internal_::Type_to_type< T >() ); - } -} - -#endif diff --git a/src/json/json_spirit_writer.cpp b/src/json/json_spirit_writer.cpp deleted file mode 100644 index d24a632cf3..0000000000 --- a/src/json/json_spirit_writer.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#include "json_spirit_writer.h" -#include "json_spirit_writer_template.h" - -void json_spirit::write( const Value& value, std::ostream& os ) -{ - write_stream( value, os, false ); -} - -void json_spirit::write_formatted( const Value& value, std::ostream& os ) -{ - write_stream( value, os, true ); -} - -std::string json_spirit::write( const Value& value ) -{ - return write_string( value, false ); -} - -std::string json_spirit::write_formatted( const Value& value ) -{ - return write_string( value, true ); -} - -#ifndef BOOST_NO_STD_WSTRING - -void json_spirit::write( const wValue& value, std::wostream& os ) -{ - write_stream( value, os, false ); -} - -void json_spirit::write_formatted( const wValue& value, std::wostream& os ) -{ - write_stream( value, os, true ); -} - -std::wstring json_spirit::write( const wValue& value ) -{ - return write_string( value, false ); -} - -std::wstring json_spirit::write_formatted( const wValue& value ) -{ - return write_string( value, true ); -} - -#endif - -void json_spirit::write( const mValue& value, std::ostream& os ) -{ - write_stream( value, os, false ); -} - -void json_spirit::write_formatted( const mValue& value, std::ostream& os ) -{ - write_stream( value, os, true ); -} - -std::string json_spirit::write( const mValue& value ) -{ - return write_string( value, false ); -} - -std::string json_spirit::write_formatted( const mValue& value ) -{ - return write_string( value, true ); -} - -#ifndef BOOST_NO_STD_WSTRING - -void json_spirit::write( const wmValue& value, std::wostream& os ) -{ - write_stream( value, os, false ); -} - -void json_spirit::write_formatted( const wmValue& value, std::wostream& os ) -{ - write_stream( value, os, true ); -} - -std::wstring json_spirit::write( const wmValue& value ) -{ - return write_string( value, false ); -} - -std::wstring json_spirit::write_formatted( const wmValue& value ) -{ - return write_string( value, true ); -} - -#endif diff --git a/src/json/json_spirit_writer.h b/src/json/json_spirit_writer.h deleted file mode 100644 index 52e14068e7..0000000000 --- a/src/json/json_spirit_writer.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef JSON_SPIRIT_WRITER -#define JSON_SPIRIT_WRITER - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_value.h" -#include <iostream> - -namespace json_spirit -{ - // functions to convert JSON Values to text, - // the "formatted" versions add whitespace to format the output nicely - - void write ( const Value& value, std::ostream& os ); - void write_formatted( const Value& value, std::ostream& os ); - std::string write ( const Value& value ); - std::string write_formatted( const Value& value ); - -#ifndef BOOST_NO_STD_WSTRING - - void write ( const wValue& value, std::wostream& os ); - void write_formatted( const wValue& value, std::wostream& os ); - std::wstring write ( const wValue& value ); - std::wstring write_formatted( const wValue& value ); - -#endif - - void write ( const mValue& value, std::ostream& os ); - void write_formatted( const mValue& value, std::ostream& os ); - std::string write ( const mValue& value ); - std::string write_formatted( const mValue& value ); - -#ifndef BOOST_NO_STD_WSTRING - - void write ( const wmValue& value, std::wostream& os ); - void write_formatted( const wmValue& value, std::wostream& os ); - std::wstring write ( const wmValue& value ); - std::wstring write_formatted( const wmValue& value ); - -#endif -} - -#endif diff --git a/src/json/json_spirit_writer_template.h b/src/json/json_spirit_writer_template.h deleted file mode 100644 index 6b4978a1ff..0000000000 --- a/src/json/json_spirit_writer_template.h +++ /dev/null @@ -1,249 +0,0 @@ -#ifndef JSON_SPIRIT_WRITER_TEMPLATE -#define JSON_SPIRIT_WRITER_TEMPLATE - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#include "json_spirit_value.h" - -#include <cassert> -#include <sstream> -#include <iomanip> - -namespace json_spirit -{ - inline char to_hex_char( unsigned int c ) - { - assert( c <= 0xF ); - - const char ch = static_cast< char >( c ); - - if( ch < 10 ) return '0' + ch; - - return 'A' - 10 + ch; - } - - template< class String_type > - String_type non_printable_to_string( unsigned int c ) - { - // Silence the warning: typedef ‘Char_type’ locally defined but not used [-Wunused-local-typedefs] - // typedef typename String_type::value_type Char_type; - - String_type result( 6, '\\' ); - - result[1] = 'u'; - - result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4; - result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4; - result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4; - result[ 2 ] = to_hex_char( c & 0x000F ); - - return result; - } - - template< typename Char_type, class String_type > - bool add_esc_char( Char_type c, String_type& s ) - { - switch( c ) - { - case '"': s += to_str< String_type >( "\\\"" ); return true; - case '\\': s += to_str< String_type >( "\\\\" ); return true; - case '\b': s += to_str< String_type >( "\\b" ); return true; - case '\f': s += to_str< String_type >( "\\f" ); return true; - case '\n': s += to_str< String_type >( "\\n" ); return true; - case '\r': s += to_str< String_type >( "\\r" ); return true; - case '\t': s += to_str< String_type >( "\\t" ); return true; - } - - return false; - } - - template< class String_type > - String_type add_esc_chars( const String_type& s ) - { - typedef typename String_type::const_iterator Iter_type; - typedef typename String_type::value_type Char_type; - - String_type result; - - const Iter_type end( s.end() ); - - for( Iter_type i = s.begin(); i != end; ++i ) - { - const Char_type c( *i ); - - if( add_esc_char( c, result ) ) continue; - - const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c ); - - if( iswprint( unsigned_c ) ) - { - result += c; - } - else - { - result += non_printable_to_string< String_type >( unsigned_c ); - } - } - - return result; - } - - // this class generates the JSON text, - // it keeps track of the indentation level etc. - // - template< class Value_type, class Ostream_type > - class Generator - { - typedef typename Value_type::Config_type Config_type; - typedef typename Config_type::String_type String_type; - typedef typename Config_type::Object_type Object_type; - typedef typename Config_type::Array_type Array_type; - typedef typename String_type::value_type Char_type; - typedef typename Object_type::value_type Obj_member_type; - - public: - - Generator( const Value_type& value, Ostream_type& os, bool pretty ) - : os_( os ) - , indentation_level_( 0 ) - , pretty_( pretty ) - { - output( value ); - } - - private: - - void output( const Value_type& value ) - { - switch( value.type() ) - { - case obj_type: output( value.get_obj() ); break; - case array_type: output( value.get_array() ); break; - case str_type: output( value.get_str() ); break; - case bool_type: output( value.get_bool() ); break; - case int_type: output_int( value ); break; - - /// Bitcoin: Added std::fixed and changed precision from 16 to 8 - case real_type: os_ << std::showpoint << std::fixed << std::setprecision(8) - << value.get_real(); break; - - case null_type: os_ << "null"; break; - default: assert( false ); - } - } - - void output( const Object_type& obj ) - { - output_array_or_obj( obj, '{', '}' ); - } - - void output( const Array_type& arr ) - { - output_array_or_obj( arr, '[', ']' ); - } - - void output( const Obj_member_type& member ) - { - output( Config_type::get_name( member ) ); space(); - os_ << ':'; space(); - output( Config_type::get_value( member ) ); - } - - void output_int( const Value_type& value ) - { - if( value.is_uint64() ) - { - os_ << value.get_uint64(); - } - else - { - os_ << value.get_int64(); - } - } - - void output( const String_type& s ) - { - os_ << '"' << add_esc_chars( s ) << '"'; - } - - void output( bool b ) - { - os_ << to_str< String_type >( b ? "true" : "false" ); - } - - template< class T > - void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char ) - { - os_ << start_char; new_line(); - - ++indentation_level_; - - for( typename T::const_iterator i = t.begin(); i != t.end(); ++i ) - { - indent(); output( *i ); - - typename T::const_iterator next = i; - - if( ++next != t.end()) - { - os_ << ','; - } - - new_line(); - } - - --indentation_level_; - - indent(); os_ << end_char; - } - - void indent() - { - if( !pretty_ ) return; - - for( int i = 0; i < indentation_level_; ++i ) - { - os_ << " "; - } - } - - void space() - { - if( pretty_ ) os_ << ' '; - } - - void new_line() - { - if( pretty_ ) os_ << '\n'; - } - - Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning - - Ostream_type& os_; - int indentation_level_; - bool pretty_; - }; - - template< class Value_type, class Ostream_type > - void write_stream( const Value_type& value, Ostream_type& os, bool pretty ) - { - Generator< Value_type, Ostream_type >( value, os, pretty ); - } - - template< class Value_type > - typename Value_type::String_type write_string( const Value_type& value, bool pretty ) - { - typedef typename Value_type::String_type::value_type Char_type; - - std::basic_ostringstream< Char_type > os; - - write_stream( value, os, pretty ); - - return os.str(); - } -} - -#endif diff --git a/src/key.cpp b/src/key.cpp index e146e47d0d..b772dff333 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -14,21 +14,7 @@ #include <secp256k1.h> #include "ecwrapper.h" -//! anonymous namespace -namespace { - -class CSecp256k1Init { -public: - CSecp256k1Init() { - secp256k1_start(SECP256K1_START_SIGN); - } - ~CSecp256k1Init() { - secp256k1_stop(); - } -}; -static CSecp256k1Init instance_of_csecp256k1; - -} // anon namespace +static secp256k1_context_t* secp256k1_context = NULL; bool CKey::Check(const unsigned char *vch) { return eccrypto::Check(vch); @@ -44,7 +30,7 @@ void CKey::MakeNewKey(bool fCompressedIn) { } bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) { - if (!secp256k1_ec_privkey_import((unsigned char*)begin(), &privkey[0], privkey.size())) + if (!secp256k1_ec_privkey_import(secp256k1_context, (unsigned char*)begin(), &privkey[0], privkey.size())) return false; fCompressed = fCompressedIn; fValid = true; @@ -57,7 +43,7 @@ CPrivKey CKey::GetPrivKey() const { int privkeylen, ret; privkey.resize(279); privkeylen = 279; - ret = secp256k1_ec_privkey_export(begin(), (unsigned char*)&privkey[0], &privkeylen, fCompressed); + ret = secp256k1_ec_privkey_export(secp256k1_context, begin(), (unsigned char*)&privkey[0], &privkeylen, fCompressed); assert(ret); privkey.resize(privkeylen); return privkey; @@ -67,7 +53,7 @@ CPubKey CKey::GetPubKey() const { assert(fValid); CPubKey result; int clen = 65; - int ret = secp256k1_ec_pubkey_create((unsigned char*)result.begin(), &clen, begin(), fCompressed); + int ret = secp256k1_ec_pubkey_create(secp256k1_context, (unsigned char*)result.begin(), &clen, begin(), fCompressed); assert((int)result.size() == clen); assert(ret); assert(result.IsValid()); @@ -81,7 +67,7 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, uint32_ int nSigLen = 72; unsigned char extra_entropy[32] = {0}; WriteLE32(extra_entropy, test_case); - int ret = secp256k1_ecdsa_sign(hash.begin(), (unsigned char*)&vchSig[0], &nSigLen, begin(), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL); + int ret = secp256k1_ecdsa_sign(secp256k1_context, hash.begin(), (unsigned char*)&vchSig[0], &nSigLen, begin(), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL); assert(ret); vchSig.resize(nSigLen); return true; @@ -106,7 +92,7 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) return false; vchSig.resize(65); int rec = -1; - int ret = secp256k1_ecdsa_sign_compact(hash.begin(), &vchSig[1], begin(), secp256k1_nonce_function_rfc6979, NULL, &rec); + int ret = secp256k1_ecdsa_sign_compact(secp256k1_context, hash.begin(), &vchSig[1], begin(), secp256k1_nonce_function_rfc6979, NULL, &rec); assert(ret); assert(rec != -1); vchSig[0] = 27 + rec + (fCompressed ? 4 : 0); @@ -114,7 +100,7 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) } bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) { - if (!secp256k1_ec_privkey_import((unsigned char*)begin(), &privkey[0], privkey.size())) + if (!secp256k1_ec_privkey_import(secp256k1_context, (unsigned char*)begin(), &privkey[0], privkey.size())) return false; fCompressed = vchPubKey.IsCompressed(); fValid = true; @@ -125,7 +111,7 @@ bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) { return VerifyPubKey(vchPubKey); } -bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const { +bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const { assert(IsValid()); assert(IsCompressed()); unsigned char out[64]; @@ -138,9 +124,9 @@ bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild assert(begin() + 32 == end()); BIP32Hash(cc, nChild, 0, begin(), out); } - memcpy(ccChild, out+32, 32); + memcpy(ccChild.begin(), out+32, 32); memcpy((unsigned char*)keyChild.begin(), begin(), 32); - bool ret = secp256k1_ec_privkey_tweak_add((unsigned char*)keyChild.begin(), out); + bool ret = secp256k1_ec_privkey_tweak_add(secp256k1_context, (unsigned char*)keyChild.begin(), out); UnlockObject(out); keyChild.fCompressed = true; keyChild.fValid = ret; @@ -152,7 +138,7 @@ bool CExtKey::Derive(CExtKey &out, unsigned int nChild) const { CKeyID id = key.GetPubKey().GetID(); memcpy(&out.vchFingerprint[0], &id, 4); out.nChild = nChild; - return key.Derive(out.key, out.vchChainCode, nChild, vchChainCode); + return key.Derive(out.key, out.chaincode, nChild, chaincode); } void CExtKey::SetMaster(const unsigned char *seed, unsigned int nSeedLen) { @@ -161,7 +147,7 @@ void CExtKey::SetMaster(const unsigned char *seed, unsigned int nSeedLen) { LockObject(out); CHMAC_SHA512(hashkey, sizeof(hashkey)).Write(seed, nSeedLen).Finalize(out); key.Set(&out[0], &out[32], true); - memcpy(vchChainCode, &out[32], 32); + memcpy(chaincode.begin(), &out[32], 32); UnlockObject(out); nDepth = 0; nChild = 0; @@ -174,7 +160,7 @@ CExtPubKey CExtKey::Neuter() const { memcpy(&ret.vchFingerprint[0], &vchFingerprint[0], 4); ret.nChild = nChild; ret.pubkey = key.GetPubKey(); - memcpy(&ret.vchChainCode[0], &vchChainCode[0], 32); + ret.chaincode = chaincode; return ret; } @@ -183,7 +169,7 @@ void CExtKey::Encode(unsigned char code[74]) const { memcpy(code+1, vchFingerprint, 4); code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF; code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF; - memcpy(code+9, vchChainCode, 32); + memcpy(code+9, chaincode.begin(), 32); code[41] = 0; assert(key.size() == 32); memcpy(code+42, key.begin(), 32); @@ -193,7 +179,7 @@ void CExtKey::Decode(const unsigned char code[74]) { nDepth = code[0]; memcpy(vchFingerprint, code+1, 4); nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8]; - memcpy(vchChainCode, code+9, 32); + memcpy(chaincode.begin(), code+9, 32); key.Set(code+42, code+74, true); } @@ -206,3 +192,32 @@ bool ECC_InitSanityCheck() { CPubKey pubkey = key.GetPubKey(); return key.VerifyPubKey(pubkey); } + + +void ECC_Start() { + assert(secp256k1_context == NULL); + + secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); + assert(ctx != NULL); + + { + // Pass in a random blinding seed to the secp256k1 context. + unsigned char seed[32]; + LockObject(seed); + GetRandBytes(seed, 32); + bool ret = secp256k1_context_randomize(ctx, seed); + assert(ret); + UnlockObject(seed); + } + + secp256k1_context = ctx; +} + +void ECC_Stop() { + secp256k1_context_t *ctx = secp256k1_context; + secp256k1_context = NULL; + + if (ctx) { + secp256k1_context_destroy(ctx); + } +} @@ -6,6 +6,7 @@ #ifndef BITCOIN_KEY_H #define BITCOIN_KEY_H +#include "pubkey.h" #include "serialize.h" #include "support/allocators/secure.h" #include "uint256.h" @@ -13,9 +14,6 @@ #include <stdexcept> #include <vector> -class CPubKey; - -struct CExtPubKey; /** * secp256k1: @@ -138,7 +136,7 @@ public: bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const; //! Derive BIP32 child key. - bool Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const; + bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const; /** * Verify thoroughly whether a private key and a public key match. @@ -157,13 +155,13 @@ struct CExtKey { unsigned char nDepth; unsigned char vchFingerprint[4]; unsigned int nChild; - unsigned char vchChainCode[32]; + ChainCode chaincode; CKey key; friend bool operator==(const CExtKey& a, const CExtKey& b) { return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild && - memcmp(&a.vchChainCode[0], &b.vchChainCode[0], 32) == 0 && a.key == b.key; + a.chaincode == b.chaincode && a.key == b.key; } void Encode(unsigned char code[74]) const; @@ -173,7 +171,13 @@ struct CExtKey { void SetMaster(const unsigned char* seed, unsigned int nSeedLen); }; -/** Check that required EC support is available at runtime */ +/** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */ +void ECC_Start(void); + +/** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */ +void ECC_Stop(void); + +/** Check that required EC support is available at runtime. */ bool ECC_InitSanityCheck(void); #endif // BITCOIN_KEY_H diff --git a/src/keystore.cpp b/src/keystore.cpp index 3bae24b7b9..cf49ba83ad 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -6,23 +6,30 @@ #include "keystore.h" #include "key.h" +#include "pubkey.h" #include "util.h" #include <boost/foreach.hpp> -bool CKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const +bool CKeyStore::AddKey(const CKey &key) { + return AddKeyPubKey(key, key.GetPubKey()); +} + +bool CBasicKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const { CKey key; - if (!GetKey(address, key)) + if (!GetKey(address, key)) { + WatchKeyMap::const_iterator it = mapWatchKeys.find(address); + if (it != mapWatchKeys.end()) { + vchPubKeyOut = it->second; + return true; + } return false; + } vchPubKeyOut = key.GetPubKey(); return true; } -bool CKeyStore::AddKey(const CKey &key) { - return AddKeyPubKey(key, key.GetPubKey()); -} - bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey) { LOCK(cs_KeyStore); @@ -58,10 +65,29 @@ bool CBasicKeyStore::GetCScript(const CScriptID &hash, CScript& redeemScriptOut) return false; } +static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut) +{ + //TODO: Use Solver to extract this? + CScript::const_iterator pc = dest.begin(); + opcodetype opcode; + std::vector<unsigned char> vch; + if (!dest.GetOp(pc, opcode, vch) || vch.size() < 33 || vch.size() > 65) + return false; + pubKeyOut = CPubKey(vch); + if (!pubKeyOut.IsFullyValid()) + return false; + if (!dest.GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG || dest.GetOp(pc, opcode, vch)) + return false; + return true; +} + bool CBasicKeyStore::AddWatchOnly(const CScript &dest) { LOCK(cs_KeyStore); setWatchOnly.insert(dest); + CPubKey pubKey; + if (ExtractPubKey(dest, pubKey)) + mapWatchKeys[pubKey.GetID()] = pubKey; return true; } @@ -69,6 +95,9 @@ bool CBasicKeyStore::RemoveWatchOnly(const CScript &dest) { LOCK(cs_KeyStore); setWatchOnly.erase(dest); + CPubKey pubKey; + if (ExtractPubKey(dest, pubKey)) + mapWatchKeys.erase(pubKey.GetID()); return true; } diff --git a/src/keystore.h b/src/keystore.h index 4a4b6d20af..b917bf20b4 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -32,7 +32,7 @@ public: virtual bool HaveKey(const CKeyID &address) const =0; virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0; virtual void GetKeys(std::set<CKeyID> &setAddress) const =0; - virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; + virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const =0; //! Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki virtual bool AddCScript(const CScript& redeemScript) =0; @@ -47,6 +47,7 @@ public: }; typedef std::map<CKeyID, CKey> KeyMap; +typedef std::map<CKeyID, CPubKey> WatchKeyMap; typedef std::map<CScriptID, CScript > ScriptMap; typedef std::set<CScript> WatchOnlySet; @@ -55,11 +56,13 @@ class CBasicKeyStore : public CKeyStore { protected: KeyMap mapKeys; + WatchKeyMap mapWatchKeys; ScriptMap mapScripts; WatchOnlySet setWatchOnly; public: bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); + bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; bool HaveKey(const CKeyID &address) const { bool result; diff --git a/src/leveldbwrapper.cpp b/src/leveldbwrapper.cpp index c353dfa6d9..26cacf95ae 100644 --- a/src/leveldbwrapper.cpp +++ b/src/leveldbwrapper.cpp @@ -58,7 +58,8 @@ CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path& path, size_t nCa } else { if (fWipe) { LogPrintf("Wiping LevelDB in %s\n", path.string()); - leveldb::DestroyDB(path.string(), options); + leveldb::Status result = leveldb::DestroyDB(path.string(), options); + HandleError(result); } TryCreateDirectory(path); LogPrintf("Opening LevelDB in %s\n", path.string()); diff --git a/src/limitedmap.h b/src/limitedmap.h index e8ea549653..5456dfc7c4 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -27,7 +27,11 @@ protected: size_type nMaxSize; public: - limitedmap(size_type nMaxSizeIn = 0) { nMaxSize = nMaxSizeIn; } + limitedmap(size_type nMaxSizeIn) + { + assert(nMaxSizeIn > 0); + nMaxSize = nMaxSizeIn; + } const_iterator begin() const { return map.begin(); } const_iterator end() const { return map.end(); } size_type size() const { return map.size(); } @@ -38,13 +42,12 @@ public: { std::pair<iterator, bool> ret = map.insert(x); if (ret.second) { - if (nMaxSize && map.size() == nMaxSize) { + if (map.size() > nMaxSize) { map.erase(rmap.begin()->second); rmap.erase(rmap.begin()); } rmap.insert(make_pair(x.second, ret.first)); } - return; } void erase(const key_type& k) { @@ -81,11 +84,11 @@ public: size_type max_size() const { return nMaxSize; } size_type max_size(size_type s) { - if (s) - while (map.size() > s) { - map.erase(rmap.begin()->second); - rmap.erase(rmap.begin()); - } + assert(s > 0); + while (map.size() > s) { + map.erase(rmap.begin()->second); + rmap.erase(rmap.begin()); + } nMaxSize = s; return nMaxSize; } diff --git a/src/main.cpp b/src/main.cpp index a6b717d57f..e919a20771 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,16 +11,27 @@ #include "chainparams.h" #include "checkpoints.h" #include "checkqueue.h" +#include "consensus/consensus.h" +#include "consensus/validation.h" +#include "hash.h" #include "init.h" #include "merkleblock.h" #include "net.h" +#include "policy/policy.h" #include "pow.h" +#include "primitives/block.h" +#include "primitives/transaction.h" +#include "script/script.h" +#include "script/sigcache.h" +#include "script/standard.h" +#include "tinyformat.h" #include "txdb.h" #include "txmempool.h" #include "ui_interface.h" #include "undo.h" #include "util.h" #include "utilmoneystr.h" +#include "utilstrencodings.h" #include "validationinterface.h" #include <sstream> @@ -28,6 +39,7 @@ #include <boost/algorithm/string/replace.hpp> #include <boost/filesystem.hpp> #include <boost/filesystem/fstream.hpp> +#include <boost/math/distributions/poisson.hpp> #include <boost/thread.hpp> using namespace std; @@ -55,9 +67,12 @@ bool fTxIndex = false; bool fHavePruned = false; bool fPruneMode = false; bool fIsBareMultisigStd = true; +bool fRequireStandard = true; bool fCheckBlockIndex = false; -unsigned int nCoinCacheSize = 5000; +bool fCheckpointsEnabled = true; +size_t nCoinCacheUsage = 5000 * 300; uint64_t nPruneTarget = 0; +bool fAlerts = DEFAULT_ALERTS; /** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */ CFeeRate minRelayTxFee = CFeeRate(1000); @@ -68,16 +83,15 @@ struct COrphanTx { CTransaction tx; NodeId fromPeer; }; -map<uint256, COrphanTx> mapOrphanTransactions; -map<uint256, set<uint256> > mapOrphanTransactionsByPrev; -void EraseOrphansFor(NodeId peer); +map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);; +map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);; +void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** * Returns true if there are nRequired or more blocks of minVersion or above - * in the last Params().ToCheckBlockUpgradeMajority() blocks, starting at pstart - * and going backwards. + * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards. */ -static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired); +static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams); static void CheckBlockIndex(); /** Constant stuff for coinbase transactions we create: */ @@ -142,18 +156,42 @@ namespace { uint32_t nBlockSequenceId = 1; /** - * Sources of received blocks, to be able to send them reject messages or ban - * them, if processing happens afterwards. Protected by cs_main. + * Sources of received blocks, saved to be able to send them reject + * messages or ban them when processing happens afterwards. Protected by + * cs_main. */ map<uint256, NodeId> mapBlockSource; + /** + * Filter for transactions that were recently rejected by + * AcceptToMemoryPool. These are not rerequested until the chain tip + * changes, at which point the entire filter is reset. Protected by + * cs_main. + * + * Without this filter we'd be re-requesting txs from each of our peers, + * increasing bandwidth consumption considerably. For instance, with 100 + * peers, half of which relay a tx we don't accept, that might be a 50x + * bandwidth increase. A flooding attacker attempting to roll-over the + * filter using minimum-sized, 60byte, transactions might manage to send + * 1000/sec if we have fast peers, so we pick 120,000 to give our peers a + * two minute window to send invs to us. + * + * Decreasing the false positive rate is fairly cheap, so we pick one in a + * million to make it highly unlikely for users to have issues with this + * filter. + * + * Memory used: 1.7MB + */ + boost::scoped_ptr<CRollingBloomFilter> recentRejects; + uint256 hashRecentRejectsChainTip; + /** 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. - int nValidatedQueuedBefore; //! Number of blocks queued with validated headers (globally) at the time this one is requested. 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<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight; @@ -214,6 +252,7 @@ struct CNodeState { int64_t nStallingSince; list<QueuedBlock> vBlocksInFlight; int nBlocksInFlight; + int nBlocksInFlightValidHeaders; //! Whether we consider this a preferred download peer. bool fPreferredDownload; @@ -227,6 +266,7 @@ struct CNodeState { fSyncStarted = false; nStallingSince = 0; nBlocksInFlight = 0; + nBlocksInFlightValidHeaders = 0; fPreferredDownload = false; } }; @@ -258,6 +298,12 @@ 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; @@ -285,30 +331,36 @@ void FinalizeNode(NodeId nodeid) { } // Requires cs_main. -void MarkBlockAsReceived(const uint256& hash) { +// Returns a bool indicating whether we requested this block. +bool MarkBlockAsReceived(const uint256& hash) { map<uint256, pair<NodeId, list<QueuedBlock>::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; state->vBlocksInFlight.erase(itInFlight->second.second); state->nBlocksInFlight--; state->nStallingSince = 0; mapBlocksInFlight.erase(itInFlight); + return true; } + return false; } // Requires cs_main. -void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, CBlockIndex *pindex = NULL) { +void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Params& consensusParams, CBlockIndex *pindex = NULL) { CNodeState *state = State(nodeid); assert(state != NULL); // Make sure it's not listed somewhere already. MarkBlockAsReceived(hash); - QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != NULL}; + int64_t nNow = GetTimeMicros(); + QueuedBlock newentry = {hash, pindex, nNow, pindex != NULL, GetBlockTimeout(nNow, nQueuedValidatedHeaders, consensusParams)}; nQueuedValidatedHeaders += newentry.fValidatedHeaders; list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry); state->nBlocksInFlight++; + state->nBlocksInFlightValidHeaders += newentry.fValidatedHeaders; mapBlocksInFlight[hash] = std::make_pair(nodeid, it); } @@ -389,7 +441,7 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBl } // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor - // of their current tip anymore. Go back enough to fix that. + // of its current tip anymore. Go back enough to fix that. state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock); if (state->pindexLastCommonBlock == state->pindexBestKnownBlock) return; @@ -416,13 +468,14 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBl // Iterate over those blocks in vToFetch (in forward direction), adding the ones that // are not yet downloaded and not in flight to vBlocks. In the mean time, update - // pindexLastCommonBlock as long as all ancestors are already downloaded. + // pindexLastCommonBlock as long as all ancestors are already downloaded, or if it's + // already part of our chain (and therefore don't need it even if pruned). BOOST_FOREACH(CBlockIndex* pindex, vToFetch) { if (!pindex->IsValid(BLOCK_VALID_TREE)) { // We consider the chain that this peer is on invalid. return; } - if (pindex->nStatus & BLOCK_HAVE_DATA) { + if (pindex->nStatus & BLOCK_HAVE_DATA || chainActive.Contains(pindex)) { if (pindex->nChainTx) state->pindexLastCommonBlock = pindex; } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) { @@ -505,7 +558,7 @@ CBlockTreeDB *pblocktree = NULL; // mapOrphanTransactions // -bool AddOrphanTx(const CTransaction& tx, NodeId peer) +bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { uint256 hash = tx.GetHash(); if (mapOrphanTransactions.count(hash)) @@ -535,7 +588,7 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer) return true; } -void static EraseOrphanTx(uint256 hash) +void static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash); if (it == mapOrphanTransactions.end()) @@ -569,7 +622,7 @@ void EraseOrphansFor(NodeId peer) } -unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) +unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { unsigned int nEvicted = 0; while (mapOrphanTransactions.size() > nMaxOrphans) @@ -585,86 +638,10 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) return nEvicted; } - - - - - - -bool IsStandardTx(const CTransaction& tx, string& reason) -{ - if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) { - reason = "version"; - return false; - } - - // Extremely large transactions with lots of inputs can cost the network - // 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) { - reason = "tx-size"; - return false; - } - - 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 - // 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) - if (txin.scriptSig.size() > 1650) { - reason = "scriptsig-size"; - return false; - } - if (!txin.scriptSig.IsPushOnly()) { - reason = "scriptsig-not-pushonly"; - return false; - } - } - - unsigned int nDataOut = 0; - txnouttype whichType; - BOOST_FOREACH(const CTxOut& txout, tx.vout) { - if (!::IsStandard(txout.scriptPubKey, whichType)) { - reason = "scriptpubkey"; - return false; - } - - if (whichType == TX_NULL_DATA) - nDataOut++; - else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) { - reason = "bare-multisig"; - return false; - } else if (txout.IsDust(::minRelayTxFee)) { - reason = "dust"; - return false; - } - } - - // only one OP_RETURN txout is permitted - if (nDataOut > 1) { - reason = "multi-op-return"; - return false; - } - - return true; -} - bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) { - AssertLockHeld(cs_main); - // Time based nLockTime implemented in 0.1.6 if (tx.nLockTime == 0) return true; - if (nBlockHeight == 0) - nBlockHeight = chainActive.Height(); - if (nBlockTime == 0) - nBlockTime = GetAdjustedTime(); if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime)) return true; BOOST_FOREACH(const CTxIn& txin, tx.vin) @@ -673,72 +650,10 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) return true; } -/** - * Check transaction inputs to mitigate two - * potential denial-of-service attacks: - * - * 1. scriptSigs with extra data stuffed into them, - * not consumed by scriptPubKey (or P2SH script) - * 2. P2SH scripts with a crazy number of expensive - * CHECKSIG/CHECKMULTISIG operations - */ -bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) +bool CheckFinalTx(const CTransaction &tx) { - if (tx.IsCoinBase()) - return true; // Coinbases don't use vin normally - - for (unsigned int i = 0; i < tx.vin.size(); i++) - { - const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]); - - vector<vector<unsigned char> > vSolutions; - txnouttype whichType; - // get the scriptPubKey corresponding to this input: - 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. - vector<vector<unsigned char> > stack; - if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker())) - return false; - - if (whichType == TX_SCRIPTHASH) - { - if (stack.empty()) - return false; - CScript subscript(stack.back().begin(), stack.back().end()); - vector<vector<unsigned char> > 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 (stack.size() != (unsigned int)nArgsExpected) - return false; - } - - return true; + AssertLockHeld(cs_main); + return IsFinalTx(tx, chainActive.Height() + 1, GetAdjustedTime()); } unsigned int GetLegacySigOpCount(const CTransaction& tx) @@ -781,30 +696,24 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) { // Basic checks that don't depend on any context if (tx.vin.empty()) - return state.DoS(10, error("CheckTransaction(): vin empty"), - REJECT_INVALID, "bad-txns-vin-empty"); + return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty"); if (tx.vout.empty()) - return state.DoS(10, error("CheckTransaction(): vout empty"), - REJECT_INVALID, "bad-txns-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) - return state.DoS(100, error("CheckTransaction(): size limits failed"), - REJECT_INVALID, "bad-txns-oversize"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize"); // Check for negative or overflow output values CAmount nValueOut = 0; BOOST_FOREACH(const CTxOut& txout, tx.vout) { if (txout.nValue < 0) - return state.DoS(100, error("CheckTransaction(): txout.nValue negative"), - REJECT_INVALID, "bad-txns-vout-negative"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-negative"); if (txout.nValue > MAX_MONEY) - return state.DoS(100, error("CheckTransaction(): txout.nValue too high"), - REJECT_INVALID, "bad-txns-vout-toolarge"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-toolarge"); nValueOut += txout.nValue; if (!MoneyRange(nValueOut)) - return state.DoS(100, error("CheckTransaction(): txout total out of range"), - REJECT_INVALID, "bad-txns-txouttotal-toolarge"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-txouttotal-toolarge"); } // Check for duplicate inputs @@ -812,23 +721,20 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) BOOST_FOREACH(const CTxIn& txin, tx.vin) { if (vInOutPoints.count(txin.prevout)) - return state.DoS(100, error("CheckTransaction(): duplicate inputs"), - REJECT_INVALID, "bad-txns-inputs-duplicate"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-duplicate"); vInOutPoints.insert(txin.prevout); } if (tx.IsCoinBase()) { if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100) - return state.DoS(100, error("CheckTransaction(): coinbase script size"), - REJECT_INVALID, "bad-cb-length"); + return state.DoS(100, false, REJECT_INVALID, "bad-cb-length"); } else { BOOST_FOREACH(const CTxIn& txin, tx.vin) if (txin.prevout.IsNull()) - return state.DoS(10, error("CheckTransaction(): prevout is null"), - REJECT_INVALID, "bad-txns-prevout-null"); + return state.DoS(10, false, REJECT_INVALID, "bad-txns-prevout-null"); } return true; @@ -863,6 +769,14 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF return nMinFee; } +/** Convert CValidationState to a human-readable message for logging */ +static std::string FormatStateMessage(const CValidationState &state) +{ + return strprintf("%s%s (code %i)", + state.GetRejectReason(), + state.GetDebugMessage().empty() ? "" : ", "+state.GetDebugMessage(), + state.GetRejectCode()); +} bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool* pfMissingInputs, bool fRejectAbsurdFee) @@ -872,44 +786,27 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa *pfMissingInputs = false; if (!CheckTransaction(tx, state)) - return error("AcceptToMemoryPool: CheckTransaction failed"); + return false; // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) - return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"), - REJECT_INVALID, "coinbase"); + return state.DoS(100, false, REJECT_INVALID, "coinbase"); // Rather not work on nonstandard transactions (unless -testnet/-regtest) string reason; - if (Params().RequireStandard() && !IsStandardTx(tx, reason)) - return state.DoS(0, - error("AcceptToMemoryPool: nonstandard transaction: %s", reason), - REJECT_NONSTANDARD, 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. - // - // However, IsFinalTx() is confusing... Without arguments, it uses - // chainActive.Height() to evaluate nLockTime; when a block is accepted, - // chainActive.Height() is set to the value of nHeight in the block. - // However, when IsFinalTx() 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 IsFinalTx() with one more than chainActive.Height(). - // - // Timestamps on the other hand don't get any special treatment, because we - // can't know what timestamp the next block will have, and there aren't - // timestamp applications where it matters. - if (!IsFinalTx(tx, chainActive.Height() + 1)) - return state.DoS(0, - error("AcceptToMemoryPool: non-final"), - REJECT_NONSTANDARD, "non-final"); + if (!CheckFinalTx(tx)) + 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 false; + return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-in-mempool"); // Check for conflicts with in-memory transactions { @@ -920,7 +817,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa if (pool.mapNextTx.count(outpoint)) { // Disable replacement feature for now - return false; + return state.Invalid(false, REJECT_CONFLICT, "txn-mempool-conflict"); } } } @@ -937,23 +834,22 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // do we already have it? if (view.HaveCoins(hash)) - return false; + return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-known"); // do all inputs exist? // Note that this does not check for the presence of actual outputs (see the next check for that), - // only helps filling in pfMissingInputs (to determine missing vs spent). + // and only helps with filling in pfMissingInputs (to determine missing vs spent). BOOST_FOREACH(const CTxIn txin, tx.vin) { if (!view.HaveCoins(txin.prevout.hash)) { if (pfMissingInputs) *pfMissingInputs = true; - return false; + return false; // fMissingInputs and !state.IsInvalid() is used to detect this condition, don't set state.Invalid() } } // are the actual inputs available? if (!view.HaveInputs(tx)) - return state.Invalid(error("AcceptToMemoryPool: inputs already spent"), - REJECT_DUPLICATE, "bad-txns-inputs-spent"); + return state.Invalid(false, REJECT_DUPLICATE, "bad-txns-inputs-spent"); // Bring the best block into scope view.GetBestBlock(); @@ -965,8 +861,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } // Check for non-standard pay-to-script-hash in inputs - if (Params().RequireStandard() && !AreInputsStandard(tx, view)) - return error("AcceptToMemoryPool: nonstandard transaction input"); + if (fRequireStandard && !AreInputsStandard(tx, view)) + return state.Invalid(false, REJECT_NONSTANDARD, "bad-txns-nonstandard-inputs"); // Check that the transaction doesn't have an excessive number of // sigops, making it impossible to mine. Since the coinbase transaction @@ -976,24 +872,21 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa unsigned int nSigOps = GetLegacySigOpCount(tx); nSigOps += GetP2SHSigOpCount(tx, view); if (nSigOps > MAX_STANDARD_TX_SIGOPS) - return state.DoS(0, - error("AcceptToMemoryPool: too many sigops %s, %d > %d", - hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS), - REJECT_NONSTANDARD, "bad-txns-too-many-sigops"); + return state.DoS(0, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false, + strprintf("%d > %d", nSigOps, MAX_STANDARD_TX_SIGOPS)); CAmount nValueOut = tx.GetValueOut(); CAmount nFees = nValueIn-nValueOut; double dPriority = view.GetPriority(tx, chainActive.Height()); - CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height()); + CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx)); unsigned int nSize = entry.GetTxSize(); // Don't accept it if it can't get into a block CAmount txMinFee = GetMinRelayFee(tx, nSize, true); if (fLimitFree && nFees < txMinFee) - return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d", - hash.ToString(), nFees, txMinFee), - REJECT_INSUFFICIENTFEE, "insufficient fee"); + return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false, + strprintf("%d < %d", nFees, txMinFee)); // Require that free transactions have sufficient priority to be mined in the next block. if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) { @@ -1018,23 +911,31 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // -limitfreerelay unit is thousand-bytes-per-minute // At default rate it would take over a month to fill 1GB if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000) - return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"), - REJECT_INSUFFICIENTFEE, "rate limited free transaction"); + return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "rate limited free transaction"); LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); dFreeCount += nSize; } if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000) - return error("AcceptToMemoryPool: absurdly high fees %s, %d > %d", - hash.ToString(), - nFees, ::minRelayTxFee.GetFee(nSize) * 10000); + return state.Invalid(false, + REJECT_HIGHFEE, "absurdly-high-fee", + strprintf("%d > %d", nFees, ::minRelayTxFee.GetFee(nSize) * 10000)); + + // Calculate in-mempool ancestors, up to a limit. + 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 (!pool.CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) { + return state.DoS(0, false, REJECT_NONSTANDARD, "too-long-mempool-chain", false, errString); + } // 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("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString()); - } + return false; // Check again against just the consensus-critical mandatory script // verification flags, in case of bugs in the standard flags that cause @@ -1047,11 +948,12 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // can be exploited as a DoS attack. if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true)) { - return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString()); + return error("%s: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s, %s", + __func__, hash.ToString(), FormatStateMessage(state)); } // Store transaction in memory - pool.addUnchecked(hash, entry); + pool.addUnchecked(hash, entry, setAncestors, !IsInitialBlockDownload()); } SyncWithWallets(tx, NULL); @@ -1063,47 +965,45 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) { CBlockIndex *pindexSlow = NULL; + + LOCK(cs_main); + + if (mempool.lookup(hash, txOut)) { - LOCK(cs_main); - { - if (mempool.lookup(hash, txOut)) - { - return true; - } - } + return true; + } - if (fTxIndex) { - CDiskTxPos postx; - if (pblocktree->ReadTxIndex(hash, postx)) { - CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION); - if (file.IsNull()) - return error("%s: OpenBlockFile failed", __func__); - CBlockHeader header; - try { - file >> header; - fseek(file.Get(), postx.nTxOffset, SEEK_CUR); - file >> txOut; - } catch (const std::exception& e) { - return error("%s: Deserialize or I/O error - %s", __func__, e.what()); - } - hashBlock = header.GetHash(); - if (txOut.GetHash() != hash) - return error("%s: txid mismatch", __func__); - return true; + if (fTxIndex) { + CDiskTxPos postx; + if (pblocktree->ReadTxIndex(hash, postx)) { + CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION); + if (file.IsNull()) + return error("%s: OpenBlockFile failed", __func__); + CBlockHeader header; + try { + file >> header; + fseek(file.Get(), postx.nTxOffset, SEEK_CUR); + file >> txOut; + } catch (const std::exception& e) { + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } + hashBlock = header.GetHash(); + if (txOut.GetHash() != hash) + return error("%s: txid mismatch", __func__); + return true; } + } - if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it - int nHeight = -1; - { - CCoinsViewCache &view = *pcoinsTip; - const CCoins* coins = view.AccessCoins(hash); - if (coins) - nHeight = coins->nHeight; - } - if (nHeight > 0) - pindexSlow = chainActive[nHeight]; + if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it + int nHeight = -1; + { + CCoinsViewCache &view = *pcoinsTip; + const CCoins* coins = view.AccessCoins(hash); + if (coins) + nHeight = coins->nHeight; } + if (nHeight > 0) + pindexSlow = chainActive[nHeight]; } if (pindexSlow) { @@ -1132,7 +1032,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock // CBlock and CBlockIndex // -bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos) +bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart) { // Open history file to append CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); @@ -1141,7 +1041,7 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos) // Write index header unsigned int nSize = fileout.GetSerializeSize(block); - fileout << FLATDATA(Params().MessageStart()) << nSize; + fileout << FLATDATA(messageStart) << nSize; // Write block long fileOutPos = ftell(fileout.Get()); @@ -1187,25 +1087,26 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex) return true; } -CAmount GetBlockValue(int nHeight, const CAmount& nFees) +CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams) { - CAmount nSubsidy = 50 * COIN; - int halvings = nHeight / Params().SubsidyHalvingInterval(); - + int halvings = nHeight / consensusParams.nSubsidyHalvingInterval; // Force block reward to zero when right shift is undefined. if (halvings >= 64) - return nFees; + return 0; + CAmount nSubsidy = 50 * COIN; // Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years. nSubsidy >>= halvings; - - return nSubsidy + nFees; + return nSubsidy; } bool IsInitialBlockDownload() { + const CChainParams& chainParams = Params(); LOCK(cs_main); - if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate()) + if (fImporting || fReindex) + return true; + if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints())) return true; static bool lockIBDState = false; if (lockIBDState) @@ -1277,8 +1178,8 @@ void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip) pfork = pfork->pprev; } - // We define a condition which we should warn the user about as a fork of at least 7 blocks - // who's tip is within 72 blocks (+/- 12 hours if no one mines it) of ours + // We define a condition where we should warn the user about as a fork of at least 7 blocks + // with a tip within 72 blocks (+/- 12 hours if no one mines it) of ours // We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network // hash rate operating on the fork. // or a chain that is entirely longer than ours and invalid (note that this should be detected by both) @@ -1324,9 +1225,11 @@ void static InvalidChainFound(CBlockIndex* pindexNew) pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexNew->GetBlockTime())); + CBlockIndex *tip = chainActive.Tip(); + assert (tip); LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__, - chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), - DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime())); + tip->GetBlockHash().ToString(), chainActive.Height(), log(tip->nChainWork.getdouble())/log(2.0), + DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime())); CheckForkWarningConditions(); } @@ -1335,7 +1238,8 @@ void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state if (state.IsInvalid(nDoS)) { std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash()); if (it != mapBlockSource.end() && State(it->second)) { - CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()}; + 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); @@ -1385,27 +1289,26 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach bool CScriptCheck::operator()() { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) { - return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error)); + return false; } return true; } -bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks) +int GetSpendHeight(const CCoinsViewCache& inputs) { - if (!tx.IsCoinBase()) - { - if (pvChecks) - pvChecks->reserve(tx.vin.size()); + LOCK(cs_main); + CBlockIndex* pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second; + return pindexPrev->nHeight + 1; +} +namespace Consensus { +bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight) +{ // This doesn't trigger the DoS code on purpose; if it did, it would make it easier // for an attacker to attempt to split the network. if (!inputs.HaveInputs(tx)) - return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString())); + return state.Invalid(false, 0, "", "Inputs unavailable"); - // While checking, GetBestBlock() refers to the parent block. - // This is also true for mempool checks. - CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second; - int nSpendHeight = pindexPrev->nHeight + 1; CAmount nValueIn = 0; CAmount nFees = 0; for (unsigned int i = 0; i < tx.vin.size(); i++) @@ -1417,33 +1320,42 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // If prev is coinbase, check that it's matured if (coins->IsCoinBase()) { if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) - return state.Invalid( - error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight), - REJECT_INVALID, "bad-txns-premature-spend-of-coinbase"); + return state.Invalid(false, + REJECT_INVALID, "bad-txns-premature-spend-of-coinbase", + strprintf("tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight)); } // Check for negative or overflow input values nValueIn += coins->vout[prevout.n].nValue; if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn)) - return state.DoS(100, error("CheckInputs(): txin values out of range"), - REJECT_INVALID, "bad-txns-inputvalues-outofrange"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputvalues-outofrange"); } if (nValueIn < tx.GetValueOut()) - return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s)", - tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())), - REJECT_INVALID, "bad-txns-in-belowout"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout", false, + strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(tx.GetValueOut()))); // Tally transaction fees CAmount nTxFee = nValueIn - tx.GetValueOut(); if (nTxFee < 0) - return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()), - REJECT_INVALID, "bad-txns-fee-negative"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-negative"); nFees += nTxFee; if (!MoneyRange(nFees)) - return state.DoS(100, error("CheckInputs(): nFees out of range"), - REJECT_INVALID, "bad-txns-fee-outofrange"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-outofrange"); + return true; +} +}// namespace Consensus + +bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks) +{ + if (!tx.IsCoinBase()) + { + if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs))) + return false; + + if (pvChecks) + pvChecks->reserve(tx.vin.size()); // The first loop above does all the inexpensive checks. // Only if ALL inputs pass do we perform expensive ECDSA signature checks. @@ -1494,7 +1406,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi namespace { -bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock) +bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart) { // Open history file to append CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); @@ -1503,7 +1415,7 @@ bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint // Write index header unsigned int nSize = fileout.GetSerializeSize(blockundo); - fileout << FLATDATA(Params().MessageStart()) << nSize; + fileout << FLATDATA(messageStart) << nSize; // Write undo data long fileOutPos = ftell(fileout.Get()); @@ -1548,6 +1460,24 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin return true; } +/** Abort with a message */ +bool AbortNode(const std::string& strMessage, const std::string& userMessage="") +{ + strMiscWarning = strMessage; + LogPrintf("*** %s\n", strMessage); + uiInterface.ThreadSafeMessageBox( + userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage, + "", CClientUIInterface::MSG_ERROR); + StartShutdown(); + return false; +} + +bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage="") +{ + AbortNode(strMessage, userMessage); + return state.Error(strMessage); +} + } // anon namespace /** @@ -1583,7 +1513,7 @@ static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const CO return fClean; } -bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean) +bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean) { assert(pindex->GetBlockHash() == view.GetBestBlock()); @@ -1683,6 +1613,68 @@ 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<double> 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; + CAlert::Notify(strWarning, true); + lastAlertTime = now; + } +} + static int64_t nTimeVerify = 0; static int64_t nTimeConnect = 0; static int64_t nTimeIndex = 0; @@ -1709,7 +1701,14 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return true; } - bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(); + bool fScriptChecks = true; + if (fCheckpointsEnabled) { + CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints()); + if (pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->nHeight) == pindex) { + // This block is an ancestor of a checkpoint: disable script checks + fScriptChecks = false; + } + } // Do not allow blocks that contain transactions which 'overwrite' older transactions, // unless those are already completely spent. @@ -1719,9 +1718,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information. // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool // already refuses previously-known transaction ids entirely. - // This rule was originally applied all blocks whose timestamp was after March 15, 2012, 0:00 UTC. + // This rule was originally applied to all blocks with a timestamp after March 15, 2012, 0:00 UTC. // Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the - // two in the chain that violate it. This prevents exploiting the issue against nodes in their + // two in the chain that violate it. This prevents exploiting the issue against nodes during their // initial block download. bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash. !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) || @@ -1742,7 +1741,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE; // Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks, when 75% of the network has upgraded: - if (block.nVersion >= 3 && IsSuperMajority(3, pindex->pprev, Params().EnforceBlockUpgradeMajority())) { + if (block.nVersion >= 3 && IsSuperMajority(3, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) { flags |= SCRIPT_VERIFY_DERSIG; } @@ -1789,7 +1788,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin std::vector<CScriptCheck> vChecks; if (!CheckInputs(tx, state, view, fScriptChecks, flags, false, nScriptCheckThreads ? &vChecks : NULL)) - return false; + return error("ConnectBlock(): CheckInputs on %s failed with %s", + tx.GetHash().ToString(), FormatStateMessage(state)); control.Add(vChecks); } @@ -1805,10 +1805,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart; LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001); - if (block.vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees)) + CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()); + if (block.vtx[0].GetValueOut() > blockReward) return state.DoS(100, error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)", - block.vtx[0].GetValueOut(), GetBlockValue(pindex->nHeight, nFees)), + block.vtx[0].GetValueOut(), blockReward), REJECT_INVALID, "bad-cb-amount"); if (!control.Wait()) @@ -1826,8 +1827,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin CDiskBlockPos pos; if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) return error("ConnectBlock(): FindUndoPos failed"); - if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash())) - return state.Abort("Failed to write undo data"); + if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart())) + return AbortNode(state, "Failed to write undo data"); // update nUndoPos in block index pindex->nUndoPos = pos.nPos; @@ -1840,7 +1841,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (fTxIndex) if (!pblocktree->WriteTxIndex(vPos)) - return state.Abort("Failed to write transaction index"); + return AbortNode(state, "Failed to write transaction index"); // add this block to the view's block chain view.SetBestBlock(pindex->GetBlockHash()); @@ -1875,11 +1876,14 @@ enum FlushStateMode { bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { LOCK2(cs_main, cs_LastBlockFile); static int64_t nLastWrite = 0; + static int64_t nLastFlush = 0; + static int64_t nLastSetChain = 0; std::set<int> setFilesToPrune; bool fFlushForPrune = false; try { if (fPruneMode && fCheckForPruning) { FindFilesToPrune(setFilesToPrune); + fCheckForPruning = false; if (!setFilesToPrune.empty()) { fFlushForPrune = true; if (!fHavePruned) { @@ -1888,16 +1892,32 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { } } } - if ((mode == FLUSH_STATE_ALWAYS) || - ((mode == FLUSH_STATE_PERIODIC || mode == FLUSH_STATE_IF_NEEDED) && pcoinsTip->GetCacheSize() > nCoinCacheSize) || - (mode == FLUSH_STATE_PERIODIC && GetTimeMicros() > nLastWrite + DATABASE_WRITE_INTERVAL * 1000000) || - fFlushForPrune) { - // Typical CCoins structures on disk are around 100 bytes in size. - // Pushing a new one to the database can cause it to be written - // twice (once in the log, and once in the tables). This is already - // an overestimation, as most will delete an existing entry or - // overwrite one. Still, use a conservative safety factor of 2. - if (!CheckDiskSpace(100 * 2 * 2 * pcoinsTip->GetCacheSize())) + int64_t nNow = GetTimeMicros(); + // Avoid writing/flushing immediately after startup. + if (nLastWrite == 0) { + nLastWrite = nNow; + } + if (nLastFlush == 0) { + nLastFlush = nNow; + } + if (nLastSetChain == 0) { + nLastSetChain = nNow; + } + size_t cacheSize = pcoinsTip->DynamicMemoryUsage(); + // The cache is large and close to the limit, but we have time now (not in the middle of a block processing). + bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize * (10.0/9) > nCoinCacheUsage; + // The cache is over the limit, we have to write now. + bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nCoinCacheUsage; + // It's been a while since we wrote the block index to disk. Do this frequently, so we don't need to redownload after a crash. + bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000; + // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage. + bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000; + // Combine all conditions that result in a full cache flush. + bool fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune; + // Write blocks and block index to disk. + if (fDoFullFlush || fPeriodicWrite) { + // Depend on nMinDiskSpace to ensure we can write block index + if (!CheckDiskSpace(0)) return state.Error("out of disk space"); // First make sure all block and undo data is flushed to disk. FlushBlockFile(); @@ -1916,27 +1936,35 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { setDirtyBlockIndex.erase(it++); } if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) { - return state.Abort("Files to write to block index database"); + return AbortNode(state, "Files to write to block index database"); } } - // Flush the chainstate (which may refer to block index entries). - if (!pcoinsTip->Flush()) - return state.Abort("Failed to write to coin database"); - // Finally remove any pruned files - if (fFlushForPrune) { + if (fFlushForPrune) UnlinkPrunedFiles(setFilesToPrune); - fCheckForPruning = false; - } - + nLastWrite = nNow; + } + // Flush best chain related state. This can only be done if the blocks / block index write was also done. + if (fDoFullFlush) { + // Typical CCoins structures on disk are around 128 bytes in size. + // Pushing a new one to the database can cause it to be written + // twice (once in the log, and once in the tables). This is already + // an overestimation, as most will delete an existing entry or + // overwrite one. Still, use a conservative safety factor of 2. + if (!CheckDiskSpace(128 * 2 * 2 * pcoinsTip->GetCacheSize())) + return state.Error("out of disk space"); + // Flush the chainstate (which may refer to block index entries). + if (!pcoinsTip->Flush()) + 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) { // Update best block in wallet (so we can detect restored wallets). - if (mode != FLUSH_STATE_IF_NEEDED) { - GetMainSignals().SetBestChain(chainActive.GetLocator()); - } - nLastWrite = GetTimeMicros(); + GetMainSignals().SetBestChain(chainActive.GetLocator()); + nLastSetChain = nNow; } } catch (const std::runtime_error& e) { - return state.Abort(std::string("System error while flushing: ") + e.what()); + return AbortNode(state, std::string("System error while flushing: ") + e.what()); } return true; } @@ -1954,16 +1982,17 @@ void PruneAndFlush() { /** Update chainActive and related internal data structures. */ void static UpdateTip(CBlockIndex *pindexNew) { + const CChainParams& chainParams = Params(); chainActive.SetTip(pindexNew); // New best block nTimeBestReceived = GetTime(); mempool.AddTransactionsUpdated(1); - LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%u\n", __func__, + 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, DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), - Checkpoints::GuessVerificationProgress(chainActive.Tip()), (unsigned int)pcoinsTip->GetCacheSize()); + Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip()), pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize()); cvBlockChange.notify_all(); @@ -1984,7 +2013,7 @@ void static UpdateTip(CBlockIndex *pindexNew) { 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!"); + strMiscWarning = _("Warning: This version is obsolete; upgrade required!"); CAlert::Notify(strMiscWarning, true); fWarned = true; } @@ -1999,7 +2028,7 @@ bool static DisconnectTip(CValidationState &state) { // Read block from disk. CBlock block; if (!ReadBlockFromDisk(block, pindexDelete)) - return state.Abort("Failed to read block"); + return AbortNode(state, "Failed to read block"); // Apply the block atomically to the chain state. int64_t nStart = GetTimeMicros(); { @@ -2013,13 +2042,23 @@ bool static DisconnectTip(CValidationState &state) { if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED)) return false; // Resurrect mempool transactions from the disconnected block. + std::vector<uint256> vHashUpdate; BOOST_FOREACH(const CTransaction &tx, block.vtx) { // ignore validation errors in resurrected transactions list<CTransaction> removed; CValidationState stateDummy; - if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) + if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) { mempool.remove(tx, removed, true); + } 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); mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight); mempool.check(pcoinsTip); // Update chainActive and related variables. @@ -2038,11 +2077,11 @@ static int64_t nTimeFlush = 0; static int64_t nTimeChainState = 0; static int64_t nTimePostConnect = 0; -/** +/** * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock * corresponding to pindexNew, to bypass loading it again from disk. */ -bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) { +bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, const CBlock *pblock) { assert(pindexNew->pprev == chainActive.Tip()); mempool.check(pcoinsTip); // Read block from disk. @@ -2050,7 +2089,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * CBlock block; if (!pblock) { if (!ReadBlockFromDisk(block, pindexNew)) - return state.Abort("Failed to read block"); + return AbortNode(state, "Failed to read block"); pblock = █ } // Apply the block atomically to the chain state. @@ -2059,7 +2098,6 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001); { CCoinsViewCache view(pcoinsTip); - CInv inv(MSG_BLOCK, pindexNew->GetBlockHash()); bool rv = ConnectBlock(*pblock, state, pindexNew, view); GetMainSignals().BlockChecked(*pblock, state); if (!rv) { @@ -2067,7 +2105,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * InvalidBlockFound(pindexNew, state); return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString()); } - mapBlockSource.erase(inv.hash); + mapBlockSource.erase(pindexNew->GetBlockHash()); nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2; LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001); assert(view.Flush()); @@ -2081,7 +2119,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001); // Remove conflicting transactions from the mempool. list<CTransaction> txConflicted; - mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted); + mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted, !IsInitialBlockDownload()); mempool.check(pcoinsTip); // Update chainActive & related variables. UpdateTip(pindexNew); @@ -2175,7 +2213,7 @@ 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, CBlockIndex *pindexMostWork, CBlock *pblock) { +static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, const CBlock *pblock) { AssertLockHeld(cs_main); bool fInvalidFound = false; const CBlockIndex *pindexOldTip = chainActive.Tip(); @@ -2244,9 +2282,10 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo * or an activated best chain. pblock is either NULL or a pointer to a block * that is already loaded (to avoid loading it again from disk). */ -bool ActivateBestChain(CValidationState &state, CBlock *pblock) { +bool ActivateBestChain(CValidationState &state, const CBlock *pblock) { CBlockIndex *pindexNewTip = NULL; CBlockIndex *pindexMostWork = NULL; + const CChainParams& chainParams = Params(); do { boost::this_thread::interruption_point(); @@ -2271,16 +2310,17 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) { if (!fInitialDownload) { uint256 hashNewTip = pindexNewTip->GetBlockHash(); // Relay inventory, but don't relay old inventory during initial block download. - int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(); - // Don't relay blocks if pruning -- could cause a peer to try to download, resulting - // in a stalled download if the block file is pruned before the request. - if (nLocalServices & NODE_NETWORK) { + int nBlockEstimate = 0; + if (fCheckpointsEnabled) + nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()); + { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip)); } // Notify external listeners about the new tip. + GetMainSignals().UpdatedBlockTip(pindexNewTip); uiInterface.NotifyBlockTip(hashNewTip); } } while(pindexMostWork != chainActive.Tip()); @@ -2315,7 +2355,7 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { } // The resulting new best tip may not be in setBlockIndexCandidates anymore, so - // add them again. + // add it again. BlockMap::iterator it = mapBlockIndex.begin(); while (it != mapBlockIndex.end()) { if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) { @@ -2543,6 +2583,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo { // These are checks that are independent of context. + if (block.fChecked) + return true; + // Check that the header is valid (particularly PoW). This is mostly // redundant with the call in AcceptBlockHeader. if (!CheckBlockHeader(block, state, fCheckPOW)) @@ -2551,7 +2594,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // Check the merkle root. if (fCheckMerkleRoot) { bool mutated; - uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated); + uint256 hashMerkleRoot2 = block.ComputeMerkleRoot(&mutated); if (block.hashMerkleRoot != hashMerkleRoot2) return state.DoS(100, error("CheckBlock(): hashMerkleRoot mismatch"), REJECT_INVALID, "bad-txnmrklroot", true); @@ -2585,7 +2628,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // Check transactions BOOST_FOREACH(const CTransaction& tx, block.vtx) if (!CheckTransaction(tx, state)) - return error("CheckBlock(): CheckTransaction failed"); + return error("CheckBlock(): CheckTransaction of %s failed with %s", + tx.GetHash().ToString(), + FormatStateMessage(state)); unsigned int nSigOps = 0; BOOST_FOREACH(const CTransaction& tx, block.vtx) @@ -2596,22 +2641,31 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"), REJECT_INVALID, "bad-blk-sigops", true); + if (fCheckPOW && fCheckMerkleRoot) + block.fChecked = true; + return true; } -bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev) +static bool CheckIndexAgainstCheckpoint(const CBlockIndex* pindexPrev, CValidationState& state, const CChainParams& chainparams, const uint256& hash) { - const Consensus::Params& consensusParams = Params().GetConsensus(); - uint256 hash = block.GetHash(); - if (hash == consensusParams.hashGenesisBlock) + if (*pindexPrev->phashBlock == chainparams.GetConsensus().hashGenesisBlock) return true; - assert(pindexPrev); - int nHeight = pindexPrev->nHeight+1; + // Don't accept any forks from the main chain prior to last checkpoint + CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints()); + if (pcheckpoint && nHeight < pcheckpoint->nHeight) + return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight)); + return true; +} + +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev) +{ + const Consensus::Params& consensusParams = Params().GetConsensus(); // Check proof of work - if (block.nBits != GetNextWorkRequired(pindexPrev, &block, Params().GetConsensus())) + if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) return state.DoS(100, error("%s: incorrect proof of work", __func__), REJECT_INVALID, "bad-diffbits"); @@ -2620,29 +2674,15 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta return state.Invalid(error("%s: block's timestamp is too early", __func__), REJECT_INVALID, "time-too-old"); - // Check that the block chain matches the known block chain up to a checkpoint - if (!Checkpoints::CheckBlock(nHeight, hash)) - return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight), - REJECT_CHECKPOINT, "checkpoint mismatch"); - - // Don't accept any forks from the main chain prior to last checkpoint - CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(); - if (pcheckpoint && nHeight < pcheckpoint->nHeight) - return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight)); - // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority())) - { + 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, Params().RejectBlockOutdatedMajority())) - { + if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) return state.Invalid(error("%s : rejected nVersion=2 block", __func__), REJECT_OBSOLETE, "bad-version"); - } return true; } @@ -2650,6 +2690,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev) { const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1; + const Consensus::Params& consensusParams = Params().GetConsensus(); // Check that all transactions are finalized BOOST_FOREACH(const CTransaction& tx, block.vtx) @@ -2659,7 +2700,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet): - if (block.nVersion >= 2 && IsSuperMajority(2, pindexPrev, Params().EnforceBlockUpgradeMajority())) + if (block.nVersion >= 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams)) { CScript expect = CScript() << nHeight; if (block.vtx[0].vin[0].scriptSig.size() < expect.size() || @@ -2679,33 +2720,37 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc uint256 hash = block.GetHash(); BlockMap::iterator miSelf = mapBlockIndex.find(hash); CBlockIndex *pindex = NULL; - if (miSelf != mapBlockIndex.end()) { - // Block header is already known. - pindex = miSelf->second; - if (ppindex) - *ppindex = pindex; - if (pindex->nStatus & BLOCK_FAILED_MASK) - return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate"); - return true; - } + if (hash != chainparams.GetConsensus().hashGenesisBlock) { - if (!CheckBlockHeader(block, state)) - return false; + if (miSelf != mapBlockIndex.end()) { + // Block header is already known. + pindex = miSelf->second; + if (ppindex) + *ppindex = pindex; + if (pindex->nStatus & BLOCK_FAILED_MASK) + return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate"); + return true; + } - // Get prev block index - CBlockIndex* pindexPrev = NULL; - if (hash != chainparams.GetConsensus().hashGenesisBlock) { + if (!CheckBlockHeader(block, state)) + return false; + + // Get prev block index + CBlockIndex* pindexPrev = NULL; BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); if (mi == mapBlockIndex.end()) return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk"); pindexPrev = (*mi).second; if (pindexPrev->nStatus & BLOCK_FAILED_MASK) return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk"); - } - if (!ContextualCheckBlockHeader(block, state, pindexPrev)) - return false; + assert(pindexPrev); + if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, hash)) + return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str()); + if (!ContextualCheckBlockHeader(block, state, pindexPrev)) + return false; + } if (pindex == NULL) pindex = AddToBlockIndex(block); @@ -2715,8 +2760,9 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc return true; } -bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, CDiskBlockPos* dbp) +bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp) { + const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); CBlockIndex *&pindex = *ppindex; @@ -2724,13 +2770,25 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, if (!AcceptBlockHeader(block, state, &pindex)) return false; - // If we're pruning, ensure that we don't allow a peer to dump a copy - // of old blocks. But we might need blocks that are not on the main chain - // to handle a reorg, even if we've processed once. - if (pindex->nStatus & BLOCK_HAVE_DATA || chainActive.Contains(pindex)) { - // TODO: deal better with duplicate blocks. - // return state.DoS(20, error("AcceptBlock(): already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()), REJECT_DUPLICATE, "duplicate"); - return true; + // Try to process all requested blocks that we don't have, but only + // process an unrequested block if it's new and has enough work to + // advance our tip, and isn't too many blocks ahead. + bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA; + bool fHasMoreWork = (chainActive.Tip() ? pindex->nChainWork > chainActive.Tip()->nChainWork : true); + // Blocks that are too out-of-order needlessly limit the effectiveness of + // pruning, because pruning will not delete block files that contain any + // blocks which are too close in height to the tip. Apply this test + // regardless of whether pruning is enabled; it should generally be safe to + // not process unrequested blocks. + bool fTooFarAhead = (pindex->nHeight > int(chainActive.Height() + MIN_BLOCKS_TO_KEEP)); + + // TODO: deal better with return value and error conditions for duplicate + // and unrequested blocks. + if (fAlreadyHave) return true; + if (!fRequested) { // If we didn't ask for it: + if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned + if (!fHasMoreWork) return true; // Don't process less-work chains + if (fTooFarAhead) return true; // Block height is too high } if ((!CheckBlock(block, state)) || !ContextualCheckBlock(block, state, pindex->pprev)) { @@ -2752,12 +2810,12 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL)) return error("AcceptBlock(): FindBlockPos failed"); if (dbp == NULL) - if (!WriteBlockToDisk(block, blockPos)) - return state.Abort("Failed to write block"); + if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) + AbortNode(state, "Failed to write block"); if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) return error("AcceptBlock(): ReceivedBlockTransactions failed"); } catch (const std::runtime_error& e) { - return state.Abort(std::string("System error: ") + e.what()); + return AbortNode(state, std::string("System error: ") + e.what()); } if (fCheckForPruning) @@ -2766,11 +2824,10 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, return true; } -static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired) +static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams) { - unsigned int nToCheck = Params().ToCheckBlockUpgradeMajority(); unsigned int nFound = 0; - for (unsigned int i = 0; i < nToCheck && nFound < nRequired && pstart != NULL; i++) + for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++) { if (pstart->nVersion >= minVersion) ++nFound; @@ -2780,21 +2837,22 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned } -bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp) +bool ProcessNewBlock(CValidationState &state, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp) { // Preliminary checks bool checked = CheckBlock(*pblock, state); { LOCK(cs_main); - MarkBlockAsReceived(pblock->GetHash()); + bool fRequested = MarkBlockAsReceived(pblock->GetHash()); + fRequested |= fForceProcessing; if (!checked) { return error("%s: CheckBlock FAILED", __func__); } // Store to disk CBlockIndex *pindex = NULL; - bool ret = AcceptBlock(*pblock, state, &pindex, dbp); + bool ret = AcceptBlock(*pblock, state, &pindex, fRequested, dbp); if (pindex && pfrom) { mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId(); } @@ -2811,8 +2869,11 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot) { + const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); - assert(pindexPrev == chainActive.Tip()); + assert(pindexPrev && pindexPrev == chainActive.Tip()); + if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, block.GetHash())) + return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str()); CCoinsViewCache viewNew(pcoinsTip); CBlockIndex indexDummy(block); @@ -2833,24 +2894,6 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex return true; } - - - - - - - -bool AbortNode(const std::string &strMessage, const std::string &userMessage) { - strMiscWarning = strMessage; - LogPrintf("*** %s\n", strMessage); - uiInterface.ThreadSafeMessageBox( - userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage, - "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return false; -} - - /** * BLOCK PRUNING CODE */ @@ -2919,7 +2962,7 @@ void FindFilesToPrune(std::set<int>& setFilesToPrune) return; } - unsigned int nLastBlockWeMustKeep = chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP; + unsigned int nLastBlockWeCanPrune = chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP; uint64_t nCurrentUsage = CalculateCurrentUsage(); // We don't check to prune until after we've allocated new space for files // So we should leave a buffer under our target to account for another allocation @@ -2938,9 +2981,9 @@ void FindFilesToPrune(std::set<int>& setFilesToPrune) if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target? break; - // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip - if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeMustKeep) - break; + // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning + if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) + continue; PruneOneBlockFile(fileNumber); // Queue up the files for removal @@ -2950,10 +2993,10 @@ void FindFilesToPrune(std::set<int>& setFilesToPrune) } } - LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB min_must_keep=%d removed %d blk/rev pairs\n", + LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n", nPruneTarget/1024/1024, nCurrentUsage/1024/1024, ((int64_t)nPruneTarget - (int64_t)nCurrentUsage)/1024/1024, - nLastBlockWeMustKeep, count); + nLastBlockWeCanPrune, count); } bool CheckDiskSpace(uint64_t nAdditionalBytes) @@ -3025,6 +3068,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash) bool static LoadBlockIndexDB() { + const CChainParams& chainparams = Params(); if (!pblocktree->LoadBlockIndexGuts()) return false; @@ -3127,7 +3171,7 @@ bool static LoadBlockIndexDB() LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__, chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), - Checkpoints::GuessVerificationProgress(chainActive.Tip())); + Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip())); return true; } @@ -3183,7 +3227,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth } } // check level 3: check for inconsistencies during memory-only disconnect of tip blocks - if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= nCoinCacheSize) { + if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) { bool fClean = true; if (!DisconnectBlock(block, state, pindex, coins, &fClean)) return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); @@ -3242,6 +3286,7 @@ void UnloadBlockIndex() setDirtyBlockIndex.clear(); setDirtyFileInfo.clear(); mapNodeState.clear(); + recentRejects.reset(NULL); BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) { delete entry.second; @@ -3260,7 +3305,12 @@ bool LoadBlockIndex() bool InitBlockIndex() { + const CChainParams& chainparams = Params(); LOCK(cs_main); + + // Initialize global variables that cannot be constructed at startup. + recentRejects.reset(new CRollingBloomFilter(120000, 0.000001)); + // Check whether we're already initialized if (chainActive.Genesis() != NULL) return true; @@ -3280,7 +3330,7 @@ bool InitBlockIndex() { CValidationState state; if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime())) return error("LoadBlockIndex(): FindBlockPos failed"); - if (!WriteBlockToDisk(block, blockPos)) + if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) return error("LoadBlockIndex(): writing genesis block to disk failed"); CBlockIndex *pindex = AddToBlockIndex(block); if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) @@ -3358,7 +3408,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) // process in case the block isn't known yet if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) { CValidationState state; - if (ProcessNewBlock(state, NULL, &block, dbp)) + if (ProcessNewBlock(state, NULL, &block, true, dbp)) nLoaded++; if (state.IsError()) break; @@ -3380,7 +3430,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(), head.ToString()); CValidationState dummy; - if (ProcessNewBlock(dummy, NULL, &block, &it->second)) + if (ProcessNewBlock(dummy, NULL, &block, true, &it->second)) { nLoaded++; queue.push_back(block.GetHash()); @@ -3391,7 +3441,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) } } } catch (const std::exception& e) { - LogPrintf("%s: Deserialize or I/O error - %s", __func__, e.what()); + LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what()); } } } catch (const std::runtime_error& e) { @@ -3592,7 +3642,7 @@ void static CheckBlockIndex() // CAlert // -string GetWarnings(string strFor) +std::string GetWarnings(const std::string& strFor) { int nPriority = 0; string strStatusBar; @@ -3657,16 +3707,27 @@ string GetWarnings(string strFor) // -bool static AlreadyHave(const CInv& inv) +bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { switch (inv.type) { case MSG_TX: { - bool txInMap = false; - txInMap = mempool.exists(inv.hash); - return txInMap || mapOrphanTransactions.count(inv.hash) || - pcoinsTip->HaveCoins(inv.hash); + assert(recentRejects); + if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip) + { + // If the chain tip has changed previously rejected transactions + // might be now valid, e.g. due to a nLockTime'd tx becoming valid, + // or a double-spend. Reset the rejects filter and give those + // txs a second chance. + hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash(); + recentRejects->reset(); + } + + return recentRejects->contains(inv.hash) || + mempool.exists(inv.hash) || + mapOrphanTransactions.count(inv.hash) || + pcoinsTip->HaveCoins(inv.hash); } case MSG_BLOCK: return mapBlockIndex.count(inv.hash); @@ -3733,7 +3794,7 @@ void static ProcessGetData(CNode* pfrom) pfrom->PushMessage("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 didnt send here - + // Note that there is currently no way for a node to request any single transactions we didn't send here - // they must either disconnect and retry or request the full block. // Thus, the protocol spec specified allows for us to provide duplicate txn here, // however we MUST always provide at least what the remote peer needs @@ -3746,7 +3807,7 @@ void static ProcessGetData(CNode* pfrom) // no response } - // Trigger them to send a getblocks request for the next batch of inventory + // Trigger the peer node to send a getblocks request for the next batch of inventory if (inv.hash == pfrom->hashContinue) { // Bypass PushInventory, this must send even if redundant, @@ -3852,7 +3913,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (!vRecv.empty()) vRecv >> addrFrom >> nNonce; if (!vRecv.empty()) { - vRecv >> LIMITED_STRING(pfrom->strSubVer, 256); + vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH); pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer); } if (!vRecv.empty()) @@ -4060,7 +4121,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (inv.type == MSG_BLOCK) { UpdateBlockAvailability(pfrom->GetId(), inv.hash); if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) { - // First request the headers preceeding the announced block. In the normal fully-synced + // First request the headers preceding the announced block. In the normal fully-synced // case where a new block is announced that succeeds the current tip (no reorganization), // there are no such headers. // Secondly, and only when we are close to being synced, we request the announced block directly, @@ -4075,7 +4136,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, 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); + MarkBlockAsInFlight(pfrom->GetId(), inv.hash, chainparams.GetConsensus()); } LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id); } @@ -4139,11 +4200,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("net", " getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); break; } + // If pruning, don't inv blocks unless we have on disk and are likely to still have + // for some reasonable time window (1 hour) that block relay might require. + const int nPrunedBlocksLikelyToHave = MIN_BLOCKS_TO_KEEP - 3600 / chainparams.GetConsensus().nPowTargetSpacing; + if (fPruneMode && (!(pindex->nStatus & BLOCK_HAVE_DATA) || pindex->nHeight <= chainActive.Tip()->nHeight - nPrunedBlocksLikelyToHave)) + { + LogPrint("net", " getblocks stopping, pruned or too old block at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); + break; + } pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash())); if (--nLimit <= 0) { - // When this block is requested, we'll send an inv that'll make them - // getblocks the next batch of inventory. + // When this block is requested, we'll send an inv that'll + // trigger the peer to getblocks the next batch of inventory. LogPrint("net", " getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); pfrom->hashContinue = pindex->GetBlockHash(); break; @@ -4160,6 +4229,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LOCK(cs_main); + if (IsInitialBlockDownload()) + return true; + CBlockIndex* pindex = NULL; if (locator.IsNull()) { @@ -4213,12 +4285,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, mempool.check(pcoinsTip); RelayTransaction(tx); vWorkQueue.push_back(inv.hash); - vEraseQueue.push_back(inv.hash); - LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n", - pfrom->id, pfrom->cleanSubVer, + LogPrint("mempool", "AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u)\n", + pfrom->id, tx.GetHash().ToString(), - mempool.mapTx.size()); + mempool.size()); // Recursively process any orphan transactions that depended on this one set<NodeId> setMisbehaving; @@ -4240,7 +4311,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // anyone relaying LegitTxX banned) CValidationState stateDummy; - vEraseQueue.push_back(orphanHash); if (setMisbehaving.count(fromPeer)) continue; @@ -4249,6 +4319,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString()); RelayTransaction(orphanTx); vWorkQueue.push_back(orphanHash); + vEraseQueue.push_back(orphanHash); } else if (!fMissingInputs2) { @@ -4260,8 +4331,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, setMisbehaving.insert(fromPeer); LogPrint("mempool", " invalid orphan tx %s\n", orphanHash.ToString()); } - // too-little-fee orphan + // Has inputs but not accepted to mempool + // 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); } mempool.check(pcoinsTip); } @@ -4279,20 +4354,34 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx); if (nEvicted > 0) LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted); - } else if (pfrom->fWhitelisted) { - // Always relay transactions received from whitelisted peers, even - // if they are already in the mempool (allowing the node to function - // as a gateway for nodes hidden behind it). - RelayTransaction(tx); + } else { + // AcceptToMemoryPool() returned false, possibly because the tx is + // already in the mempool; if the tx isn't in the mempool that + // means it was rejected and we shouldn't ask for it again. + if (!mempool.exists(tx.GetHash())) { + assert(recentRejects); + recentRejects->insert(tx.GetHash()); + } + if (pfrom->fWhitelisted) { + // Always relay transactions received from whitelisted peers, even + // if they were rejected from the mempool, allowing the node to + // function as a gateway for nodes hidden behind it. + // + // FIXME: This includes invalid transactions, which means a + // whitelisted peer could get us banned! We may want to change + // that. + RelayTransaction(tx); + } } int nDoS = 0; if (state.IsInvalid(nDoS)) { - LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(), - pfrom->id, pfrom->cleanSubVer, - state.GetRejectReason()); - pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), - state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); + LogPrint("mempoolrej", "%s from peer=%d was not accepted: %s\n", tx.GetHash().ToString(), + pfrom->id, + FormatStateMessage(state)); + if (state.GetRejectCode() < REJECT_INTERNAL) // Never send AcceptToMemoryPool's internal codes over P2P + pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), + state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0) Misbehaving(pfrom->GetId(), nDoS); } @@ -4364,9 +4453,15 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->AddInventoryKnown(inv); CValidationState state; - ProcessNewBlock(state, pfrom, &block); + // Process all blocks from whitelisted peers, even if not requested, + // unless we're still syncing with the network. + // Such an unrequested block may still be processed, subject to the + // conditions in AcceptBlock(). + bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload(); + ProcessNewBlock(state, pfrom, &block, forceProcessing, NULL); 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(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0) { @@ -4380,9 +4475,9 @@ 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 users (which are behind NAT and can only make outgoing connections) ignore - // getaddr message mitigates the attack. + // 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)) { pfrom->vAddrToSend.clear(); @@ -4459,6 +4554,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (pingUsecTime > 0) { // Successful ping time measurement, replace previous pfrom->nPingUsecTime = pingUsecTime; + pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime); } else { // This should never happen sProblem = "Timing mishap"; @@ -4467,7 +4563,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Nonce mismatches are normal when pings are overlapping sProblem = "Nonce mismatch"; if (nonce == 0) { - // This is most likely a bug in another implementation somewhere, cancel this ping + // This is most likely a bug in another implementation somewhere; cancel this ping bPingFinished = true; sProblem = "Nonce zero"; } @@ -4476,15 +4572,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, sProblem = "Unsolicited pong without ping"; } } else { - // This is most likely a bug in another implementation somewhere, cancel this ping + // This is most likely a bug in another implementation somewhere; cancel this ping bPingFinished = true; sProblem = "Short payload"; } if (!(sProblem.empty())) { - LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n", + LogPrint("net", "pong peer=%d: %s, %x expected, %x received, %u bytes\n", pfrom->id, - pfrom->cleanSubVer, sProblem, pfrom->nPingNonceSent, nonce, @@ -4496,7 +4591,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "alert") + else if (fAlerts && strCommand == "alert") { CAlert alert; vRecv >> alert; @@ -4527,6 +4622,21 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } + else if (!(nLocalServices & NODE_BLOOM) && + (strCommand == "filterload" || + strCommand == "filteradd" || + strCommand == "filterclear") && + //TODO: Remove this line after reasonable network upgrade + pfrom->nVersion >= NO_BLOOM_VERSION) + { + if (pfrom->nVersion >= NO_BLOOM_VERSION) + Misbehaving(pfrom->GetId(), 100); + //TODO: Enable this after reasonable network upgrade + //else + // pfrom->fDisconnect = true; + } + + else if (strCommand == "filterload") { CBloomFilter filter; @@ -4735,7 +4845,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) { const Consensus::Params& consensusParams = Params().GetConsensus(); { - // Don't send anything until we get their version message + // Don't send anything until we get its version message if (pto->nVersion == 0) return true; @@ -4781,7 +4891,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) { // Periodically clear addrKnown to allow refresh broadcasts if (nLastRebroadcast) - pnode->addrKnown.clear(); + pnode->addrKnown.reset(); // Rebroadcast our address AdvertizeLocal(pnode); @@ -4826,7 +4936,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString()); else { - CNode::Ban(pto->addr); + CNode::Ban(pto->addr, BanReasonNodeMisbehaving); } } state.fShouldBan = false; @@ -4919,11 +5029,24 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // 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 - // being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes + // being saturated. We only count validated in-flight blocks so peers can't advertise non-existing block hashes // to unreasonably increase our timeout. - if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * consensusParams.nPowTargetSpacing * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) { - LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id); - pto->fDisconnect = true; + // 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) { + LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->id); + pto->fDisconnect = true; + } } // @@ -4936,7 +5059,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) 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(), pindex); + MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex); LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(), pindex->nHeight, pto->id); } diff --git a/src/main.h b/src/main.h index b0aec6662d..a6001eed8f 100644 --- a/src/main.h +++ b/src/main.h @@ -12,19 +12,10 @@ #include "amount.h" #include "chain.h" -#include "chainparams.h" #include "coins.h" -#include "consensus/consensus.h" #include "net.h" -#include "primitives/block.h" -#include "primitives/transaction.h" -#include "script/script.h" -#include "script/sigcache.h" -#include "script/standard.h" +#include "script/script_error.h" #include "sync.h" -#include "tinyformat.h" -#include "txmempool.h" -#include "uint256.h" #include <algorithm> #include <exception> @@ -42,24 +33,24 @@ class CBlockTreeDB; class CBloomFilter; class CInv; class CScriptCheck; +class CTxMemPool; class CValidationInterface; class CValidationState; struct CNodeStateStats; -/** Default for -blockmaxsize and -blockminsize, which control the range of sizes 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 = 50000; -/** The maximum size for transactions we're willing to relay/mine */ -static const unsigned int MAX_STANDARD_TX_SIZE = 100000; -/** 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; +/** Default for accepting alerts from the P2P network. */ +static const bool DEFAULT_ALERTS = true; /** 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 */ +static const unsigned int DEFAULT_ANCESTOR_LIMIT = 100; +/** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */ +static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT = 900; +/** Default for -limitdescendantcount, max number of in-mempool descendants */ +static const unsigned int DEFAULT_DESCENDANT_LIMIT = 1000; +/** Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants */ +static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 2500; /** The maximum size of a blk?????.dat file (since 0.8) */ static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB /** The pre-allocation chunk size for blk?????.dat files (since 0.8) */ @@ -75,28 +66,20 @@ static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16; /** Timeout in seconds during which a peer must stall block download progress before being disconnected. */ 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 their tip. Changing this value is a protocol upgrade. */ + * less than this number, we reached its tip. Changing this value is a protocol upgrade. */ static const unsigned int MAX_HEADERS_RESULTS = 2000; /** 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 * harder). We'll probably want to make this a per-peer adaptive value at some point. */ static const unsigned int BLOCK_DOWNLOAD_WINDOW = 1024; -/** Time to wait (in seconds) between writing blockchain state to disk. */ -static const unsigned int DATABASE_WRITE_INTERVAL = 3600; +/** Time to wait (in seconds) between writing blocks/block index to disk. */ +static const unsigned int DATABASE_WRITE_INTERVAL = 60 * 60; +/** Time to wait (in seconds) between flushing chainstate to disk. */ +static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60; /** Maximum length of reject messages. */ static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111; -/** "reject" message codes */ -static const unsigned char REJECT_MALFORMED = 0x01; -static const unsigned char REJECT_INVALID = 0x10; -static const unsigned char REJECT_OBSOLETE = 0x11; -static const unsigned char REJECT_DUPLICATE = 0x12; -static const unsigned char REJECT_NONSTANDARD = 0x40; -static const unsigned char REJECT_DUST = 0x41; -static const unsigned char REJECT_INSUFFICIENTFEE = 0x42; -static const unsigned char REJECT_CHECKPOINT = 0x43; - struct BlockHasher { size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); } @@ -117,9 +100,12 @@ extern bool fReindex; extern int nScriptCheckThreads; extern bool fTxIndex; extern bool fIsBareMultisigStd; +extern bool fRequireStandard; extern bool fCheckBlockIndex; -extern unsigned int nCoinCacheSize; +extern bool fCheckpointsEnabled; +extern size_t nCoinCacheUsage; extern CFeeRate minRelayTxFee; +extern bool fAlerts; /** Best header we've seen so far (used for getheaders queries' starting points). */ extern CBlockIndex *pindexBestHeader; @@ -135,7 +121,7 @@ extern bool fPruneMode; /** Number of MiB of block files that we're trying to stay below. */ extern uint64_t nPruneTarget; /** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of chainActive.Tip() will not be pruned. */ -static const signed int MIN_BLOCKS_TO_KEEP = 288; +static const unsigned int MIN_BLOCKS_TO_KEEP = 288; // Require that user allocate at least 550MB for block & undo files (blk???.dat and rev???.dat) // At 1MB per block, 288 blocks = 288MB. @@ -145,7 +131,7 @@ static const signed int MIN_BLOCKS_TO_KEEP = 288; // full block file chunks, we need the high water mark which triggers the prune to be // one 128MB block file + added 15% undo data = 147MB greater for a total of 545MB // Setting the target to > than 550MB will make it likely we can respect the target. -static const signed int MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024; +static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024; /** Register with a network node to receive its signals */ void RegisterNodeSignals(CNodeSignals& nodeSignals); @@ -160,10 +146,11 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals); * @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[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. * @return True if state.IsValid() */ -bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp = NULL); +bool ProcessNewBlock(CValidationState &state, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, 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) */ @@ -191,15 +178,17 @@ bool ProcessMessages(CNode* pfrom); bool SendMessages(CNode* pto, bool fSendTrickle); /** 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 */ -std::string GetWarnings(std::string strFor); +std::string GetWarnings(const std::string& strFor); /** Retrieve a transaction (from memory pool, or from disk, if possible) */ bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false); /** Find the best known block, and make it the tip of the block chain */ -bool ActivateBestChain(CValidationState &state, CBlock *pblock = NULL); -CAmount GetBlockValue(int nHeight, const CAmount& nFees); +bool ActivateBestChain(CValidationState &state, const CBlock *pblock = NULL); +CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams); /** * Prune block and undo files (blk???.dat and undo???.dat) so that the disk space used is less than a user-defined target. @@ -225,8 +214,6 @@ void UnlinkPrunedFiles(std::set<int>& setFilesToPrune); /** Create a new block index entry for a given block hash */ CBlockIndex * InsertBlockIndex(uint256 hash); -/** Abort with a message */ -bool AbortNode(const std::string &msg, const std::string &userMessage=""); /** Get statistics from node state */ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats); /** Increase a node's misbehavior score. */ @@ -276,25 +263,6 @@ struct CDiskTxPos : public CDiskBlockPos CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree); -/** - * 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 - * script can be anything; an attacker could use a very - * expensive-to-check-upon-redemption script like: - * DUP CHECKSIG DROP ... repeated 100 times... OP_1 - */ - -/** - * Check for standard transaction types - * @param[in] mapInputs Map of previous transactions that have outputs we're spending - * @return True if all inputs (scriptSigs) use only standard transaction forms - */ -bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs); - /** * Count ECDSA signature operations the old-fashioned (pre-0.6) way * @return number of sigops this transaction's outputs will produce when spent @@ -326,12 +294,18 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach /** Context-independent validity checks */ bool CheckTransaction(const CTransaction& tx, CValidationState& state); -/** Check for standard transaction types - * @return True if all outputs (scriptPubKeys) use only standard transaction forms +/** + * Check if transaction is final and can be included in a block with the + * specified height and time. Consensus critical. */ -bool IsStandardTx(const CTransaction& tx, std::string& reason); +bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime); -bool IsFinalTx(const CTransaction &tx, int nBlockHeight = 0, int64_t nBlockTime = 0); +/** + * Check if transaction will be final in the next block to be created. + * + * Calls IsFinalTx() with current block height and appropriate block time. + */ +bool CheckFinalTx(const CTransaction &tx); /** * Closure representing one script verification @@ -369,7 +343,7 @@ public: /** Functions for disk access for blocks */ -bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos); +bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos); bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex); @@ -380,7 +354,7 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex); * 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(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL); +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); @@ -396,8 +370,8 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn /** 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 CBlock& block, CBlockIndex *pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true); -/** Store block on disk. If dbp is provided, the file is known to already reside on disk */ -bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex **pindex, CDiskBlockPos* dbp = NULL); +/** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */ +bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp); bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL); @@ -456,69 +430,6 @@ public: } }; -/** Capture information about block/transaction validation */ -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; - int nDoS; - std::string strRejectReason; - unsigned char chRejectCode; - bool corruptionPossible; -public: - CValidationState() : mode(MODE_VALID), nDoS(0), chRejectCode(0), corruptionPossible(false) {} - bool DoS(int level, bool ret = false, - unsigned char chRejectCodeIn=0, std::string strRejectReasonIn="", - bool corruptionIn=false) { - chRejectCode = chRejectCodeIn; - strRejectReason = strRejectReasonIn; - corruptionPossible = corruptionIn; - if (mode == MODE_ERROR) - return ret; - nDoS += level; - mode = MODE_INVALID; - return ret; - } - bool Invalid(bool ret = false, - unsigned char _chRejectCode=0, std::string _strRejectReason="") { - return DoS(0, ret, _chRejectCode, _strRejectReason); - } - bool Error(std::string strRejectReasonIn="") { - if (mode == MODE_VALID) - strRejectReason = strRejectReasonIn; - mode = MODE_ERROR; - return false; - } - bool Abort(const std::string &msg) { - AbortNode(msg); - return Error(msg); - } - bool IsValid() const { - return mode == MODE_VALID; - } - bool IsInvalid() const { - return mode == MODE_INVALID; - } - bool IsError() const { - return mode == MODE_ERROR; - } - bool IsInvalid(int &nDoSOut) const { - if (IsInvalid()) { - nDoSOut = nDoS; - return true; - } - return false; - } - bool CorruptionPossible() const { - return corruptionPossible; - } - unsigned char GetRejectCode() const { return chRejectCode; } - std::string GetRejectReason() const { return strRejectReason; } -}; - /** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */ class CVerifyDB { public: @@ -545,4 +456,23 @@ extern CCoinsViewCache *pcoinsTip; /** Global variable that points to the active block tree (protected by cs_main) */ extern CBlockTreeDB *pblocktree; +/** + * Return the spend height, which is one more than the inputs.GetBestBlock(). + * While checking, GetBestBlock() refers to the parent block. (protected by cs_main) + * This is also true for mempool checks. + */ +int GetSpendHeight(const CCoinsViewCache& inputs); + +/** 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. + */ +static const unsigned int REJECT_INTERNAL = 0x100; +/** Too high fee. Can not be triggered by P2P transactions */ +static const unsigned int REJECT_HIGHFEE = 0x100; +/** Transaction is already known (either in mempool or blockchain) */ +static const unsigned int REJECT_ALREADY_KNOWN = 0x101; +/** Transaction conflicts with a transaction already known */ +static const unsigned int REJECT_CONFLICT = 0x102; + #endif // BITCOIN_MAIN_H diff --git a/src/memusage.h b/src/memusage.h new file mode 100644 index 0000000000..b475c3313b --- /dev/null +++ b/src/memusage.h @@ -0,0 +1,124 @@ +// Copyright (c) 2015 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_MEMUSAGE_H +#define BITCOIN_MEMUSAGE_H + +#include <stdlib.h> + +#include <map> +#include <set> +#include <vector> + +#include <boost/foreach.hpp> +#include <boost/unordered_set.hpp> +#include <boost/unordered_map.hpp> + +namespace memusage +{ + +/** Compute the total memory used by allocating alloc bytes. */ +static size_t MallocUsage(size_t alloc); + +/** Dynamic memory usage for built-in types is zero. */ +static inline size_t DynamicUsage(const int8_t& v) { return 0; } +static inline size_t DynamicUsage(const uint8_t& v) { return 0; } +static inline size_t DynamicUsage(const int16_t& v) { return 0; } +static inline size_t DynamicUsage(const uint16_t& v) { return 0; } +static inline size_t DynamicUsage(const int32_t& v) { return 0; } +static inline size_t DynamicUsage(const uint32_t& v) { return 0; } +static inline size_t DynamicUsage(const int64_t& v) { return 0; } +static inline size_t DynamicUsage(const uint64_t& v) { return 0; } +static inline size_t DynamicUsage(const float& v) { return 0; } +static inline size_t DynamicUsage(const double& v) { return 0; } +template<typename X> static inline size_t DynamicUsage(X * const &v) { return 0; } +template<typename X> static inline size_t DynamicUsage(const X * const &v) { return 0; } + +/** Compute the memory used for dynamically allocated but owned data structures. + * For generic data types, this is *not* recursive. DynamicUsage(vector<vector<int> >) + * will compute the memory used for the vector<int>'s, but not for the ints inside. + * This is for efficiency reasons, as these functions are intended to be fast. If + * application data structures require more accurate inner accounting, they should + * iterate themselves, or use more efficient caching + updating on modification. + */ + +static inline size_t MallocUsage(size_t alloc) +{ + // Measured on libc6 2.19 on Linux. + if (sizeof(void*) == 8) { + return ((alloc + 31) >> 4) << 4; + } else if (sizeof(void*) == 4) { + return ((alloc + 15) >> 3) << 3; + } else { + assert(0); + } +} + +// STL data structures + +template<typename X> +struct stl_tree_node +{ +private: + int color; + void* parent; + void* left; + void* right; + X x; +}; + +template<typename X> +static inline size_t DynamicUsage(const std::vector<X>& v) +{ + return MallocUsage(v.capacity() * sizeof(X)); +} + +template<typename X, typename Y> +static inline size_t DynamicUsage(const std::set<X, Y>& s) +{ + return MallocUsage(sizeof(stl_tree_node<X>)) * s.size(); +} + +template<typename X, typename Y> +static inline size_t IncrementalDynamicUsage(const std::set<X, Y>& s) +{ + return MallocUsage(sizeof(stl_tree_node<X>)); +} + +template<typename X, typename Y, typename Z> +static inline size_t DynamicUsage(const std::map<X, Y, Z>& m) +{ + return MallocUsage(sizeof(stl_tree_node<std::pair<const X, Y> >)) * m.size(); +} + +template<typename X, typename Y, typename Z> +static inline size_t IncrementalDynamicUsage(const std::map<X, Y, Z>& m) +{ + return MallocUsage(sizeof(stl_tree_node<std::pair<const X, Y> >)); +} + +// Boost data structures + +template<typename X> +struct boost_unordered_node : private X +{ +private: + void* ptr; +}; + +template<typename X, typename Y> +static inline size_t DynamicUsage(const boost::unordered_set<X, Y>& s) +{ + return MallocUsage(sizeof(boost_unordered_node<X>)) * s.size() + MallocUsage(sizeof(void*) * s.bucket_count()); +} + +template<typename X, typename Y, typename Z> +static inline size_t DynamicUsage(const boost::unordered_map<X, Y, Z>& m) +{ + return MallocUsage(sizeof(boost_unordered_node<std::pair<const X, Y> >)) * m.size() + MallocUsage(sizeof(void*) * m.bucket_count()); +} + +} + +#endif diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index dc87d0377a..f8e877df25 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -119,8 +119,8 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns if (pos*2+1 < CalcTreeWidth(height-1)) { right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch); if (right == left) { - // If the left and right branch should never be identical as the transaction - // hashes covered by them must be unique. + // The left and right branches should never be identical, as the transaction + // hashes covered by them must each be unique. fBad = true; } } else { @@ -168,7 +168,7 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) { // traverse the partial tree unsigned int nBitsUsed = 0, nHashUsed = 0; uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch); - // verify that no problems occured during the tree traversal + // verify that no problems occurred during the tree traversal if (fBad) return uint256(); // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence) diff --git a/src/merkleblock.h b/src/merkleblock.h index d90face17c..904c22abc2 100644 --- a/src/merkleblock.h +++ b/src/merkleblock.h @@ -104,7 +104,7 @@ public: } } - /** Construct a partial merkle tree from a list of transaction id's, and a mask that selects a subset of them */ + /** Construct a partial merkle tree from a list of transaction ids, and a mask that selects a subset of them */ CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch); CPartialMerkleTree(); diff --git a/src/miner.cpp b/src/miner.cpp index 56a2c5828b..42c8bb970b 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -6,19 +6,23 @@ #include "miner.h" #include "amount.h" +#include "chain.h" #include "chainparams.h" +#include "coins.h" #include "consensus/consensus.h" +#include "consensus/validation.h" #include "hash.h" #include "main.h" #include "net.h" +#include "policy/policy.h" #include "pow.h" #include "primitives/transaction.h" +#include "script/standard.h" #include "timedata.h" +#include "txmempool.h" #include "util.h" #include "utilmoneystr.h" -#ifdef ENABLE_WALLET -#include "wallet/wallet.h" -#endif +#include "validationinterface.h" #include <boost/thread.hpp> #include <boost/tuple/tuple.hpp> @@ -80,17 +84,24 @@ public: } }; -void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev) +int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev) { - pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + int64_t nOldTime = pblock->nTime; + int64_t nNewTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + + if (nOldTime < nNewTime) + pblock->nTime = nNewTime; // Updating time can change work required on testnet: if (consensusParams.fPowAllowMinDifficultyBlocks) pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams); + + return nNewTime - nOldTime; } CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) { + const CChainParams& chainparams = Params(); // Create new block auto_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate()); if(!pblocktemplate.get()) @@ -136,6 +147,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) LOCK2(cs_main, mempool.cs); CBlockIndex* pindexPrev = chainActive.Tip(); const int nHeight = pindexPrev->nHeight + 1; + pblock->nTime = GetAdjustedTime(); CCoinsViewCache view(pcoinsTip); // Priority order to process transactions @@ -146,11 +158,11 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // This vector will be sorted into a priority queue: vector<TxPriority> vecPriority; vecPriority.reserve(mempool.mapTx.size()); - for (map<uint256, CTxMemPoolEntry>::iterator mi = mempool.mapTx.begin(); + for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) { - const CTransaction& tx = mi->second.GetTx(); - if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight)) + const CTransaction& tx = mi->GetTx(); + if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, pblock->nTime)) continue; COrphan* porphan = NULL; @@ -184,7 +196,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) } mapDependers[txin.prevout.hash].push_back(porphan); porphan->setDependsOn.insert(txin.prevout.hash); - nTotalIn += mempool.mapTx[txin.prevout.hash].GetTx().vout[txin.prevout.n].nValue; + nTotalIn += mempool.mapTx.find(txin.prevout.hash)->GetTx().vout[txin.prevout.n].nValue; continue; } const CCoins* coins = view.AccessCoins(txin.prevout.hash); @@ -214,7 +226,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) porphan->feeRate = feeRate; } else - vecPriority.push_back(TxPriority(dPriority, feeRate, &mi->second.GetTx())); + vecPriority.push_back(TxPriority(dPriority, feeRate, &(mi->GetTx()))); } // Collect transactions into block @@ -320,7 +332,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize); // Compute final coinbase transaction. - txNew.vout[0].nValue = GetBlockValue(nHeight, nFees); + 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; @@ -340,7 +352,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) return pblocktemplate.release(); } -void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce) +void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce) { // Update nExtraNonce static uint256 hashPrevBlock; @@ -356,10 +368,9 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& assert(txCoinbase.vin[0].scriptSig.size() <= 100); pblock->vtx[0] = txCoinbase; - pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + pblock->hashMerkleRoot = pblock->ComputeMerkleRoot(); } -#ifdef ENABLE_WALLET ////////////////////////////////////////////////////////////////////////////// // // Internal miner @@ -398,17 +409,7 @@ bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phas } } -CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) -{ - CPubKey pubkey; - if (!reservekey.GetReservedKey(pubkey)) - return NULL; - - CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; - return CreateNewBlock(scriptPubKey); -} - -static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) +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)); @@ -420,41 +421,49 @@ static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& rese return error("BitcoinMiner: generated block is stale"); } - // Remove key from key pool - reservekey.KeepKey(); - - // Track how many getdata requests this block gets - { - LOCK(wallet.cs_wallet); - wallet.mapRequestCount[pblock->GetHash()] = 0; - } + // 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, NULL, pblock)) + if (!ProcessNewBlock(state, NULL, pblock, true, NULL)) return error("BitcoinMiner: ProcessNewBlock, block not accepted"); return true; } -void static BitcoinMiner(CWallet *pwallet) +void static BitcoinMiner(const CChainParams& chainparams) { LogPrintf("BitcoinMiner started\n"); SetThreadPriority(THREAD_PRIORITY_LOWEST); RenameThread("bitcoin-miner"); - const CChainParams& chainparams = Params(); - // Each thread has its own key and counter - CReserveKey reservekey(pwallet); unsigned int nExtraNonce = 0; + boost::shared_ptr<CReserveScript> 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. - while (vNodes.empty()) + do { + bool fvNodesEmpty; + { + LOCK(cs_vNodes); + fvNodesEmpty = vNodes.empty(); + } + if (!fvNodesEmpty && !IsInitialBlockDownload()) + break; MilliSleep(1000); + } while (true); } // @@ -463,7 +472,7 @@ void static BitcoinMiner(CWallet *pwallet) unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); CBlockIndex* pindexPrev = chainActive.Tip(); - auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey)); + auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript)); if (!pblocktemplate.get()) { LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n"); @@ -495,8 +504,9 @@ void static BitcoinMiner(CWallet *pwallet) SetThreadPriority(THREAD_PRIORITY_NORMAL); LogPrintf("BitcoinMiner:\n"); LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex()); - ProcessBlockFound(pblock, *pwallet, reservekey); + ProcessBlockFound(pblock, chainparams); SetThreadPriority(THREAD_PRIORITY_LOWEST); + coinbaseScript->KeepScript(); // In regression test mode, stop mining after a block is found. if (chainparams.MineBlocksOnDemand()) @@ -519,7 +529,9 @@ void static BitcoinMiner(CWallet *pwallet) break; // Update nTime every few seconds - UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); + 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: @@ -533,19 +545,19 @@ void static BitcoinMiner(CWallet *pwallet) LogPrintf("BitcoinMiner terminated\n"); throw; } + catch (const std::runtime_error &e) + { + LogPrintf("BitcoinMiner runtime error: %s\n", e.what()); + return; + } } -void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads) +void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainparams) { static boost::thread_group* minerThreads = NULL; - if (nThreads < 0) { - // In regtest threads defaults to 1 - if (Params().DefaultMinerThreads()) - nThreads = Params().DefaultMinerThreads(); - else - nThreads = boost::thread::hardware_concurrency(); - } + if (nThreads < 0) + nThreads = GetNumCores(); if (minerThreads != NULL) { @@ -559,7 +571,5 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads) minerThreads = new boost::thread_group(); for (int i = 0; i < nThreads; i++) - minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet)); + minerThreads->create_thread(boost::bind(&BitcoinMiner, boost::cref(chainparams))); } - -#endif // ENABLE_WALLET diff --git a/src/miner.h b/src/miner.h index 96a6b70ecd..7e0e58d540 100644 --- a/src/miner.h +++ b/src/miner.h @@ -11,6 +11,7 @@ #include <stdint.h> class CBlockIndex; +class CChainParams; class CReserveKey; class CScript; class CWallet; @@ -24,12 +25,11 @@ struct CBlockTemplate }; /** Run the miner threads */ -void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads); +void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainparams); /** Generate a new block, without valid proof-of-work */ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); -CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); /** Modify the extranonce in a block */ -void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); -void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev); +void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce); +int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev); #endif // BITCOIN_MINER_H diff --git a/src/net.cpp b/src/net.cpp index 2de04fc574..87c4f0af0a 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -12,9 +12,12 @@ #include "addrman.h" #include "chainparams.h" #include "clientversion.h" +#include "crypto/common.h" +#include "hash.h" #include "primitives/transaction.h" +#include "scheduler.h" #include "ui_interface.h" -#include "crypto/common.h" +#include "utilstrencodings.h" #ifdef WIN32 #include <string.h> @@ -77,8 +80,9 @@ static CNode* pnodeLocalHost = NULL; uint64_t nLocalHostNonce = 0; static std::vector<ListenSocket> vhListenSocket; CAddrMan addrman; -int nMaxConnections = 125; +int nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS; bool fAddressesInitialized = false; +std::string strSubVersion; vector<CNode*> vNodes; CCriticalSection cs_vNodes; @@ -106,7 +110,7 @@ boost::condition_variable messageHandlerCondition; static CNodeSignals g_signals; CNodeSignals& GetNodeSignals() { return g_signals; } -void AddOneShot(string strDest) +void AddOneShot(const std::string& strDest) { LOCK(cs_vOneShots); vOneShots.push_back(strDest); @@ -331,6 +335,15 @@ CNode* FindNode(const CNetAddr& ip) return NULL; } +CNode* FindNode(const CSubNet& subNet) +{ + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if (subNet.Match((CNetAddr)pnode->addr)) + return (pnode); + return NULL; +} + CNode* FindNode(const std::string& addrName) { LOCK(cs_vNodes); @@ -375,6 +388,12 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) : ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed)) { + if (!IsSelectableSocket(hSocket)) { + LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n"); + CloseSocket(hSocket); + return NULL; + } + addrman.Attempt(addrConnect); // Add node @@ -426,19 +445,22 @@ 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("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, - nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight, true); + nLocalHostNonce, strSubVersion, nBestHeight, true); } -std::map<CNetAddr, int64_t> CNode::setBanned; +banmap_t CNode::setBanned; CCriticalSection CNode::cs_setBanned; +bool CNode::setBannedIsDirty; void CNode::ClearBanned() { + LOCK(cs_setBanned); setBanned.clear(); + setBannedIsDirty = true; } bool CNode::IsBanned(CNetAddr ip) @@ -446,25 +468,114 @@ bool CNode::IsBanned(CNetAddr ip) bool fResult = false; { LOCK(cs_setBanned); - std::map<CNetAddr, int64_t>::iterator i = setBanned.find(ip); - if (i != setBanned.end()) + for (banmap_t::iterator it = setBanned.begin(); it != setBanned.end(); it++) { - int64_t t = (*i).second; - if (GetTime() < t) + CSubNet subNet = (*it).first; + CBanEntry banEntry = (*it).second; + + if(subNet.Match(ip) && GetTime() < banEntry.nBanUntil) fResult = true; } } return fResult; } -bool CNode::Ban(const CNetAddr &addr) { - int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban +bool CNode::IsBanned(CSubNet subnet) +{ + bool fResult = false; { LOCK(cs_setBanned); - if (setBanned[addr] < banTime) - setBanned[addr] = banTime; + banmap_t::iterator i = setBanned.find(subnet); + if (i != setBanned.end()) + { + CBanEntry banEntry = (*i).second; + if (GetTime() < banEntry.nBanUntil) + fResult = true; + } } - return true; + return fResult; +} + +void CNode::Ban(const CNetAddr& addr, const BanReason &banReason, int64_t bantimeoffset, bool sinceUnixEpoch) { + CSubNet subNet(addr); + Ban(subNet, banReason, bantimeoffset, sinceUnixEpoch); +} + +void CNode::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t bantimeoffset, bool sinceUnixEpoch) { + CBanEntry banEntry(GetTime()); + banEntry.banReason = banReason; + if (bantimeoffset <= 0) + { + bantimeoffset = GetArg("-bantime", 60*60*24); // Default 24-hour ban + sinceUnixEpoch = false; + } + banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime() )+bantimeoffset; + + + LOCK(cs_setBanned); + if (setBanned[subNet].nBanUntil < banEntry.nBanUntil) + setBanned[subNet] = banEntry; + + setBannedIsDirty = true; +} + +bool CNode::Unban(const CNetAddr &addr) { + CSubNet subNet(addr); + return Unban(subNet); +} + +bool CNode::Unban(const CSubNet &subNet) { + LOCK(cs_setBanned); + if (setBanned.erase(subNet)) + { + setBannedIsDirty = true; + return true; + } + return false; +} + +void CNode::GetBanned(banmap_t &banMap) +{ + LOCK(cs_setBanned); + banMap = setBanned; //create a thread safe copy +} + +void CNode::SetBanned(const banmap_t &banMap) +{ + LOCK(cs_setBanned); + setBanned = banMap; + setBannedIsDirty = true; +} + +void CNode::SweepBanned() +{ + int64_t now = GetTime(); + + LOCK(cs_setBanned); + banmap_t::iterator it = setBanned.begin(); + while(it != setBanned.end()) + { + CBanEntry banEntry = (*it).second; + if(now > banEntry.nBanUntil) + { + setBanned.erase(it++); + setBannedIsDirty = true; + } + else + ++it; + } +} + +bool CNode::BannedSetIsDirty() +{ + LOCK(cs_setBanned); + return setBannedIsDirty; +} + +void CNode::SetBannedSetDirty(bool dirty) +{ + LOCK(cs_setBanned); //reuse setBanned lock for the isDirty flag + setBannedIsDirty = dirty; } @@ -517,6 +628,7 @@ void CNode::copyStats(CNodeStats &stats) // Raw ping time is in microseconds, but show it to user as whole seconds (Bitcoin users should be well used to small numbers with many decimal places by now :) stats.dPingTime = (((double)nPingUsecTime) / 1e6); + stats.dPingMin = (((double)nMinPingUsecTime) / 1e6); stats.dPingWait = (((double)nPingUsecWait) / 1e6); // Leave string empty if addrLocal invalid (not filled in yet) @@ -547,7 +659,7 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes) return false; if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) { - LogPrint("net", "Oversized message from peer=%i, disconnecting", GetId()); + LogPrint("net", "Oversized message from peer=%i, disconnecting\n", GetId()); return false; } @@ -664,6 +776,222 @@ void SocketSendData(CNode *pnode) static list<CNode*> 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; +}; + +static bool ReverseCompareNodeMinPingTime(const CNodeRef &a, const CNodeRef &b) +{ + return a->nMinPingUsecTime > b->nMinPingUsecTime; +} + +static bool ReverseCompareNodeTimeConnected(const CNodeRef &a, const CNodeRef &b) +{ + return a->nTimeConnected > b->nTimeConnected; +} + +class CompareNetGroupKeyed +{ + std::vector<unsigned char> vchSecretKey; +public: + CompareNetGroupKeyed() + { + vchSecretKey.resize(32, 0); + GetRandBytes(vchSecretKey.data(), vchSecretKey.size()); + } + + bool operator()(const CNodeRef &a, const CNodeRef &b) + { + std::vector<unsigned char> vchGroupA, vchGroupB; + CSHA256 hashA, hashB; + std::vector<unsigned char> 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 AttemptToEvictConnection(bool fPreferNewConnection) { + std::vector<CNodeRef> vEvictionCandidates; + { + LOCK(cs_vNodes); + + BOOST_FOREACH(CNode *node, vNodes) { + if (node->fWhitelisted) + continue; + if (!node->fInbound) + continue; + if (node->fDisconnect) + continue; + if (node->addr.IsLocal()) + continue; + vEvictionCandidates.push_back(CNodeRef(node)); + } + } + + if (vEvictionCandidates.empty()) return false; + + // 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); + vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end()); + + if (vEvictionCandidates.empty()) return false; + + // Protect the 8 nodes with the best ping times. + // 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<int>(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 existing implicit behavior. + std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected); + vEvictionCandidates.erase(vEvictionCandidates.end() - static_cast<int>(vEvictionCandidates.size() / 2), vEvictionCandidates.end()); + + if (vEvictionCandidates.empty()) return false; + + // Identify the network group with the most connections + std::vector<unsigned char> naMostConnections; + unsigned int nMostConnections = 0; + std::map<std::vector<unsigned char>, std::vector<CNodeRef> > mapAddrCounts; + BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) { + mapAddrCounts[node->addr.GetGroup()].push_back(node); + + if (mapAddrCounts[node->addr.GetGroup()].size() > nMostConnections) { + nMostConnections = mapAddrCounts[node->addr.GetGroup()].size(); + naMostConnections = node->addr.GetGroup(); + } + } + + // 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 + 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); + vEvictionCandidates[0]->fDisconnect = true; + + return true; +} + +static void AcceptConnection(const ListenSocket& hListenSocket) { + struct sockaddr_storage sockaddr; + socklen_t len = sizeof(sockaddr); + SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len); + CAddress addr; + int nInbound = 0; + int nMaxInbound = nMaxConnections - MAX_OUTBOUND_CONNECTIONS; + + if (hSocket != INVALID_SOCKET) + if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) + LogPrintf("Warning: Unknown socket family\n"); + + bool whitelisted = hListenSocket.whitelisted || CNode::IsWhitelistedRange(addr); + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if (pnode->fInbound) + nInbound++; + } + + if (hSocket == INVALID_SOCKET) + { + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK) + LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr)); + return; + } + + if (!IsSelectableSocket(hSocket)) + { + LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString()); + CloseSocket(hSocket); + return; + } + + if (CNode::IsBanned(addr) && !whitelisted) + { + LogPrintf("connection from %s dropped (banned)\n", addr.ToString()); + CloseSocket(hSocket); + return; + } + + if (nInbound >= nMaxInbound) + { + if (!AttemptToEvictConnection(whitelisted)) { + // No connection to evict, disconnect the new connection + LogPrint("net", "failed to find an eviction candidate - connection dropped (full)\n"); + CloseSocket(hSocket); + return; + } + } + + CNode* pnode = new CNode(hSocket, addr, "", true); + pnode->AddRef(); + pnode->fWhitelisted = whitelisted; + + LogPrint("net", "connection from %s accepted\n", addr.ToString()); + + { + LOCK(cs_vNodes); + vNodes.push_back(pnode); + } +} + void ThreadSocketHandler() { unsigned int nPrevNodeCount = 0; @@ -821,50 +1149,7 @@ void ThreadSocketHandler() { if (hListenSocket.socket != INVALID_SOCKET && FD_ISSET(hListenSocket.socket, &fdsetRecv)) { - struct sockaddr_storage sockaddr; - socklen_t len = sizeof(sockaddr); - SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len); - CAddress addr; - int nInbound = 0; - - if (hSocket != INVALID_SOCKET) - if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) - LogPrintf("Warning: Unknown socket family\n"); - - bool whitelisted = hListenSocket.whitelisted || CNode::IsWhitelistedRange(addr); - { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - if (pnode->fInbound) - nInbound++; - } - - if (hSocket == INVALID_SOCKET) - { - int nErr = WSAGetLastError(); - if (nErr != WSAEWOULDBLOCK) - LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr)); - } - else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS) - { - CloseSocket(hSocket); - } - else if (CNode::IsBanned(addr) && !whitelisted) - { - LogPrintf("connection from %s dropped (banned)\n", addr.ToString()); - CloseSocket(hSocket); - } - else - { - CNode* pnode = new CNode(hSocket, addr, "", true); - pnode->AddRef(); - pnode->fWhitelisted = whitelisted; - - { - LOCK(cs_vNodes); - vNodes.push_back(pnode); - } - } + AcceptConnection(hListenSocket); } } @@ -994,10 +1279,14 @@ void ThreadMapPort() #ifndef UPNPDISCOVER_SUCCESS /* miniupnpc 1.5 */ devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0); -#else +#elif MINIUPNPC_API_VERSION < 14 /* miniupnpc 1.6 */ int error = 0; devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); +#else + /* miniupnpc 1.9.20150730 */ + int error = 0; + devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error); #endif struct UPNPUrls urls; @@ -1123,7 +1412,7 @@ void ThreadDNSAddressSeed() vector<CAddress> vAdd; if (LookupHost(seed.host.c_str(), vIPs)) { - BOOST_FOREACH(CNetAddr& ip, vIPs) + BOOST_FOREACH(const CNetAddr& ip, vIPs) { int nOneDay = 24*3600; CAddress addr = CAddress(CService(ip, Params().GetDefaultPort())); @@ -1161,6 +1450,17 @@ void DumpAddresses() addrman.size(), GetTimeMillis() - nStart); } +void DumpData() +{ + DumpAddresses(); + + if (CNode::BannedSetIsDirty()) + { + DumpBanlist(); + CNode::SetBannedSetDirty(false); + } +} + void static ProcessOneShot() { string strDest; @@ -1187,7 +1487,7 @@ void ThreadOpenConnections() for (int64_t nLoop = 0;; nLoop++) { ProcessOneShot(); - BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"]) + BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-connect"]) { CAddress addr; OpenNetworkConnection(addr, NULL, strAddr.c_str()); @@ -1290,10 +1590,10 @@ void ThreadOpenAddedConnections() list<string> lAddresses(0); { LOCK(cs_vAddedNodes); - BOOST_FOREACH(string& strAddNode, vAddedNodes) + BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) lAddresses.push_back(strAddNode); } - BOOST_FOREACH(string& strAddNode, lAddresses) { + BOOST_FOREACH(const std::string& strAddNode, lAddresses) { CAddress addr; CSemaphoreGrant grant(*semOutbound); OpenNetworkConnection(addr, &grant, strAddNode.c_str()); @@ -1308,20 +1608,19 @@ void ThreadOpenAddedConnections() list<string> lAddresses(0); { LOCK(cs_vAddedNodes); - BOOST_FOREACH(string& strAddNode, vAddedNodes) + BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) lAddresses.push_back(strAddNode); } list<vector<CService> > lservAddressesToAdd(0); - BOOST_FOREACH(string& strAddNode, lAddresses) - { + BOOST_FOREACH(const std::string& strAddNode, lAddresses) { vector<CService> vservNode(0); if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0)) { lservAddressesToAdd.push_back(vservNode); { LOCK(cs_setservAddNodeAddresses); - BOOST_FOREACH(CService& serv, vservNode) + BOOST_FOREACH(const CService& serv, vservNode) setservAddNodeAddresses.insert(serv); } } @@ -1332,7 +1631,7 @@ void ThreadOpenAddedConnections() LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++) - BOOST_FOREACH(CService& addrNode, *(it)) + BOOST_FOREACH(const CService& addrNode, *(it)) if (pnode->addr == addrNode) { it = lservAddressesToAdd.erase(it); @@ -1362,7 +1661,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) || FindNode(addrConnect.ToStringIPPort())) return false; - } else if (FindNode(pszDest)) + } else if (FindNode(std::string(pszDest))) return false; CNode* pnode = ConnectNode(addrConnect, pszDest); @@ -1384,7 +1683,7 @@ void ThreadMessageHandler() { boost::mutex condition_mutex; boost::unique_lock<boost::mutex> lock(condition_mutex); - + SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL); while (true) { @@ -1475,6 +1774,13 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste LogPrintf("%s\n", strError); return false; } + if (!IsSelectableSocket(hListenSocket)) + { + strError = "Error: Couldn't create a listenable socket for incoming connections"; + LogPrintf("%s\n", strError); + return false; + } + #ifndef WIN32 #ifdef SO_NOSIGPIPE @@ -1482,8 +1788,10 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)); #endif // Allow binding if the port is still in TIME_WAIT state after - // the program was closed and restarted. Not an issue on windows! + // the program was closed and restarted. setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); +#else + setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nOne, sizeof(int)); #endif // Set to non-blocking, incoming connections will also inherit this @@ -1590,7 +1898,7 @@ void static Discover(boost::thread_group& threadGroup) #endif } -void StartNode(boost::thread_group& threadGroup) +void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) { uiInterface.InitMessage(_("Loading addresses...")); // Load addresses for peers.dat @@ -1600,6 +1908,17 @@ void StartNode(boost::thread_group& threadGroup) if (!adb.Read(addrman)) LogPrintf("Invalid or missing peers.dat; recreating\n"); } + + //try to read stored banlist + CBanDB bandb; + banmap_t banmap; + if (!bandb.Read(banmap)) + 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; @@ -1640,7 +1959,7 @@ void StartNode(boost::thread_group& threadGroup) threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "msghand", &ThreadMessageHandler)); // Dump network addresses - threadGroup.create_thread(boost::bind(&LoopForever<void (*)()>, "dumpaddr", &DumpAddresses, DUMP_ADDRESSES_INTERVAL * 1000)); + scheduler.scheduleEvery(&DumpData, DUMP_ADDRESSES_INTERVAL); } bool StopNode() @@ -1653,7 +1972,7 @@ bool StopNode() if (fAddressesInitialized) { - DumpAddresses(); + DumpData(); fAddressesInitialized = false; } @@ -1857,11 +2176,11 @@ bool CAddrDB::Read(CAddrMan& addr) return error("%s: Failed to open file %s", __func__, pathAddr.string()); // use file size to size memory buffer - int fileSize = boost::filesystem::file_size(pathAddr); - int dataSize = fileSize - sizeof(uint256); + uint64_t fileSize = boost::filesystem::file_size(pathAddr); + uint64_t dataSize = 0; // Don't try to resize to a negative number if file is small - if (dataSize < 0) - dataSize = 0; + if (fileSize >= sizeof(uint256)) + dataSize = fileSize - sizeof(uint256); vector<unsigned char> vchData; vchData.resize(dataSize); uint256 hashIn; @@ -1905,9 +2224,9 @@ bool CAddrDB::Read(CAddrMan& addr) unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); } unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); } -CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fInboundIn) : +CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), - addrKnown(5000, 0.001, insecure_rand()), + addrKnown(5000, 0.001), setInventoryKnown(SendBufferSize() / 1000) { nServices = 0; @@ -1942,6 +2261,7 @@ CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fIn nPingUsecStart = 0; nPingUsecTime = 0; fPingQueued = false; + nMinPingUsecTime = std::numeric_limits<int64_t>::max(); { LOCK(cs_nLastNodeId); @@ -2032,8 +2352,10 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend) Fuzz(GetArg("-fuzzmessagestest", 10)); if (ssSend.size() == 0) + { + LEAVE_CRITICAL_SECTION(cs_vSend); return; - + } // Set the size unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE; WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize); @@ -2057,3 +2379,119 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend) LEAVE_CRITICAL_SECTION(cs_vSend); } + +// +// CBanDB +// + +CBanDB::CBanDB() +{ + pathBanlist = GetDataDir() / "banlist.dat"; +} + +bool CBanDB::Write(const banmap_t& banSet) +{ + // Generate random temporary filename + unsigned short randv = 0; + GetRandBytes((unsigned char*)&randv, sizeof(randv)); + std::string tmpfn = strprintf("banlist.dat.%04x", randv); + + // serialize banlist, checksum data up to that point, then append csum + CDataStream ssBanlist(SER_DISK, CLIENT_VERSION); + ssBanlist << FLATDATA(Params().MessageStart()); + ssBanlist << banSet; + uint256 hash = Hash(ssBanlist.begin(), ssBanlist.end()); + ssBanlist << hash; + + // open temp output file, and associate with CAutoFile + boost::filesystem::path pathTmp = GetDataDir() / tmpfn; + FILE *file = fopen(pathTmp.string().c_str(), "wb"); + CAutoFile fileout(file, SER_DISK, CLIENT_VERSION); + if (fileout.IsNull()) + return error("%s: Failed to open file %s", __func__, pathTmp.string()); + + // Write and commit header, data + try { + fileout << ssBanlist; + } + catch (const std::exception& e) { + return error("%s: Serialize or I/O error - %s", __func__, e.what()); + } + FileCommit(fileout.Get()); + fileout.fclose(); + + // replace existing banlist.dat, if any, with new banlist.dat.XXXX + if (!RenameOver(pathTmp, pathBanlist)) + return error("%s: Rename-into-place failed", __func__); + + return true; +} + +bool CBanDB::Read(banmap_t& banSet) +{ + // open input file, and associate with CAutoFile + FILE *file = fopen(pathBanlist.string().c_str(), "rb"); + CAutoFile filein(file, SER_DISK, CLIENT_VERSION); + if (filein.IsNull()) + return error("%s: Failed to open file %s", __func__, pathBanlist.string()); + + // use file size to size memory buffer + uint64_t fileSize = boost::filesystem::file_size(pathBanlist); + uint64_t dataSize = 0; + // Don't try to resize to a negative number if file is small + if (fileSize >= sizeof(uint256)) + dataSize = fileSize - sizeof(uint256); + vector<unsigned char> vchData; + vchData.resize(dataSize); + uint256 hashIn; + + // read data and checksum from file + try { + filein.read((char *)&vchData[0], dataSize); + filein >> hashIn; + } + catch (const std::exception& e) { + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); + } + filein.fclose(); + + CDataStream ssBanlist(vchData, SER_DISK, CLIENT_VERSION); + + // verify stored checksum matches input data + uint256 hashTmp = Hash(ssBanlist.begin(), ssBanlist.end()); + if (hashIn != hashTmp) + return error("%s: Checksum mismatch, data corrupted", __func__); + + unsigned char pchMsgTmp[4]; + try { + // de-serialize file header (network specific magic number) and .. + ssBanlist >> FLATDATA(pchMsgTmp); + + // ... 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) + + CBanDB bandb; + banmap_t banmap; + CNode::GetBanned(banmap); + bandb.Write(banmap); + + LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", + banmap.size(), GetTimeMillis() - nStart); +} @@ -8,7 +8,6 @@ #include "bloom.h" #include "compat.h" -#include "hash.h" #include "limitedmap.h" #include "mruset.h" #include "netbase.h" @@ -17,7 +16,6 @@ #include "streams.h" #include "sync.h" #include "uint256.h" -#include "utilstrencodings.h" #include <deque> #include <stdint.h> @@ -31,7 +29,7 @@ #include <boost/signals2/signal.hpp> class CAddrMan; -class CBlockIndex; +class CScheduler; class CNode; namespace boost { @@ -48,6 +46,8 @@ static const unsigned int MAX_INV_SZ = 50000; 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 strSubVer in `version` message */ +static const unsigned int MAX_SUBVERSION_LENGTH = 256; /** -listen default */ static const bool DEFAULT_LISTEN = true; /** -upnp default */ @@ -58,13 +58,16 @@ static const bool DEFAULT_UPNP = false; #endif /** The maximum number of entries in mapAskFor */ static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ; +/** The maximum number of peer connections to maintain. */ +static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125; unsigned int ReceiveFloodSize(); unsigned int SendBufferSize(); -void AddOneShot(std::string strDest); +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* ConnectNode(CAddress addrConnect, const char *pszDest = NULL); @@ -72,7 +75,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu void MapPort(bool fUseUPnP); unsigned short GetListenPort(); bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false); -void StartNode(boost::thread_group& threadGroup); +void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler); bool StopNode(); void SocketSendData(CNode *pnode); @@ -139,6 +142,8 @@ extern bool fListen; extern uint64_t nLocalServices; extern uint64_t nLocalHostNonce; extern CAddrMan addrman; + +/** Maximum number of connections to simultaneously allow (aka connection slots) */ extern int nMaxConnections; extern std::vector<CNode*> vNodes; @@ -154,6 +159,9 @@ extern CCriticalSection cs_vAddedNodes; extern NodeId nLastNodeId; extern CCriticalSection cs_nLastNodeId; +/** Subversion as sent to the P2P network in `version` messages */ +extern std::string strSubVersion; + struct LocalServiceInfo { int nScore; int nPort; @@ -181,6 +189,7 @@ public: bool fWhitelisted; double dPingTime; double dPingWait; + double dPingMin; std::string addrLocal; }; @@ -226,8 +235,66 @@ public: }; +typedef enum BanReason +{ + BanReasonUnknown = 0, + BanReasonNodeMisbehaving = 1, + BanReasonManuallyAdded = 2 +} BanReason; + +class CBanEntry +{ +public: + static const int CURRENT_VERSION=1; + int nVersion; + int64_t nCreateTime; + int64_t nBanUntil; + uint8_t banReason; + + CBanEntry() + { + SetNull(); + } + + CBanEntry(int64_t nCreateTimeIn) + { + SetNull(); + nCreateTime = nCreateTimeIn; + } + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(nCreateTime); + READWRITE(nBanUntil); + READWRITE(banReason); + } + + void SetNull() + { + nVersion = CBanEntry::CURRENT_VERSION; + nCreateTime = 0; + nBanUntil = 0; + banReason = BanReasonUnknown; + } + std::string banReasonToString() + { + switch (banReason) { + case BanReasonNodeMisbehaving: + return "node misbehabing"; + case BanReasonManuallyAdded: + return "manually added"; + default: + return "unknown"; + } + } +}; +typedef std::map<CSubNet, CBanEntry> banmap_t; /** Information about a peer */ class CNode @@ -271,8 +338,8 @@ public: bool fDisconnect; // We use fRelayTxes for two purposes - // a) it allows us to not relay tx invs before receiving the peer's version message - // b) the peer may tell us in their version message that we should not relay tx invs - // until they have initialized their bloom filter. + // b) the peer may tell us in its version message that we should not relay tx invs + // until it has initialized its bloom filter. bool fRelayTxes; CSemaphoreGrant grantOutbound; CCriticalSection cs_filter; @@ -283,8 +350,9 @@ protected: // Denial-of-service detection/prevention // Key is IP address, value is banned-until-time - static std::map<CNetAddr, int64_t> setBanned; + static banmap_t setBanned; static CCriticalSection cs_setBanned; + static bool setBannedIsDirty; // Whitelisted ranges. Any node connecting from these is automatically // whitelisted (as well as those connecting to whitelisted binds). @@ -317,10 +385,12 @@ public: int64_t nPingUsecStart; // Last measured round-trip time. int64_t nPingUsecTime; + // Best measured round-trip time. + int64_t nMinPingUsecTime; // Whether a ping is requested. bool fPingQueued; - CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false); + CNode(SOCKET hSocketIn, const CAddress &addrIn, const std::string &addrNameIn = "", bool fInboundIn = false); ~CNode(); private: @@ -605,7 +675,21 @@ public: // new code. static void ClearBanned(); // needed for unit testing static bool IsBanned(CNetAddr ip); - static bool Ban(const CNetAddr &ip); + static bool IsBanned(CSubNet subnet); + static void Ban(const CNetAddr &ip, const BanReason &banReason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false); + static void Ban(const CSubNet &subNet, const BanReason &banReason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false); + static bool Unban(const CNetAddr &ip); + static bool Unban(const CSubNet &ip); + static void GetBanned(banmap_t &banmap); + static void SetBanned(const banmap_t &banmap); + + //!check is the banlist has unwritten changes + static bool BannedSetIsDirty(); + //!set the "dirty" flag for the banlist + static void SetBannedSetDirty(bool dirty=true); + //!clean unused entries (if bantime has expired) + static void SweepBanned(); + void copyStats(CNodeStats &stats); static bool IsWhitelistedRange(const CNetAddr &ip); @@ -636,4 +720,17 @@ public: bool Read(CAddrMan& addr); }; +/** Access to the banlist database (banlist.dat) */ +class CBanDB +{ +private: + boost::filesystem::path pathBanlist; +public: + CBanDB(); + bool Write(const banmap_t& banSet); + bool Read(banmap_t& banSet); +}; + +void DumpBanlist(); + #endif // BITCOIN_NET_H diff --git a/src/netbase.cpp b/src/netbase.cpp index 2015d0271a..c3d56d9184 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -35,8 +35,6 @@ #define MSG_NOSIGNAL 0 #endif -using namespace std; - // Settings static proxyType proxyInfo[NET_MAX]; static proxyType nameProxy; @@ -268,6 +266,9 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock } else { // Other error or blocking int nErr = WSAGetLastError(); if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) { + if (!IsSelectableSocket(hSocket)) { + return false; + } struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait)); fd_set fdset; FD_ZERO(&fdset); @@ -348,7 +349,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials } if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) { CloseSocket(hSocket); - return error("Proxy authentication unsuccesful"); + return error("Proxy authentication unsuccessful"); } } else if (pchRet1[1] == 0x00) { // Perform no authentication @@ -597,13 +598,13 @@ bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout, b bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed) { - string strDest; + std::string strDest; int port = portDefault; if (outProxyConnectionFailed) *outProxyConnectionFailed = false; - SplitHostPort(string(pszDest), port, strDest); + SplitHostPort(std::string(pszDest), port, strDest); proxyType nameProxy; GetNameProxy(nameProxy); @@ -982,7 +983,7 @@ std::vector<unsigned char> CNetAddr::GetGroup() const nBits -= 8; } if (nBits > 0) - vchRet.push_back(GetByte(15 - nStartByte) | ((1 << nBits) - 1)); + vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1)); return vchRet; } @@ -1252,15 +1253,15 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup) std::string strNetmask = strSubnet.substr(slash + 1); int32_t n; // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n - int noffset = network.IsIPv4() ? (12 * 8) : 0; + const int astartofs = network.IsIPv4() ? 12 : 0; if (ParseInt32(strNetmask, &n)) // If valid number, assume /24 symtex { - if(n >= 0 && n <= (128 - noffset)) // Only valid if in range of bits of address + if(n >= 0 && n <= (128 - astartofs*8)) // Only valid if in range of bits of address { - n += noffset; + n += astartofs*8; // Clear bits [n..127] for (; n < 128; ++n) - netmask[n>>3] &= ~(1<<(n&7)); + netmask[n>>3] &= ~(1<<(7-(n&7))); } else { @@ -1271,12 +1272,10 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup) { if (LookupHost(strNetmask.c_str(), vIP, 1, false)) // Never allow lookup for netmask { - // Remember: GetByte returns bytes in reversed order // Copy only the *last* four bytes in case of IPv4, the rest of the mask should stay 1's as // we don't want pchIPv4 to be part of the mask. - int asize = network.IsIPv4() ? 4 : 16; - for(int x=0; x<asize; ++x) - netmask[15-x] = vIP[0].GetByte(x); + for(int x=astartofs; x<16; ++x) + netmask[x] = vIP[0].ip[x]; } else { @@ -1289,6 +1288,17 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup) { valid = false; } + + // Normalize network according to netmask + for(int x=0; x<16; ++x) + network.ip[x] &= netmask[x]; +} + +CSubNet::CSubNet(const CNetAddr &addr): + valid(addr.IsValid()) +{ + memset(netmask, 255, sizeof(netmask)); + network = addr; } bool CSubNet::Match(const CNetAddr &addr) const @@ -1296,22 +1306,62 @@ bool CSubNet::Match(const CNetAddr &addr) const if (!valid || !addr.IsValid()) return false; for(int x=0; x<16; ++x) - if ((addr.GetByte(x) & netmask[15-x]) != network.GetByte(x)) + if ((addr.ip[x] & netmask[x]) != network.ip[x]) return false; return true; } +static inline int NetmaskBits(uint8_t x) +{ + switch(x) { + case 0x00: return 0; break; + case 0x80: return 1; break; + case 0xc0: return 2; break; + case 0xe0: return 3; break; + case 0xf0: return 4; break; + case 0xf8: return 5; break; + case 0xfc: return 6; break; + case 0xfe: return 7; break; + case 0xff: return 8; break; + default: return -1; break; + } +} + std::string CSubNet::ToString() const { + /* Parse binary 1{n}0{N-n} to see if mask can be represented as /n */ + int cidr = 0; + bool valid_cidr = true; + int n = network.IsIPv4() ? 12 : 0; + for (; n < 16 && netmask[n] == 0xff; ++n) + cidr += 8; + if (n < 16) { + int bits = NetmaskBits(netmask[n]); + if (bits < 0) + valid_cidr = false; + else + cidr += bits; + ++n; + } + for (; n < 16 && valid_cidr; ++n) + if (netmask[n] != 0x00) + valid_cidr = false; + + /* Format output */ std::string strNetmask; - if (network.IsIPv4()) - strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]); - else - strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x", - netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3], - netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7], - netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11], - netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]); + if (valid_cidr) { + strNetmask = strprintf("%u", cidr); + } else { + if (network.IsIPv4()) + strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]); + else + strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x", + netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3], + netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7], + netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11], + netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]); + } + return network.ToString() + "/" + strNetmask; } @@ -1330,6 +1380,11 @@ bool operator!=(const CSubNet& a, const CSubNet& b) return !(a==b); } +bool operator<(const CSubNet& a, const CSubNet& b) +{ + return (a.network < b.network || (a.network == b.network && memcmp(a.netmask, b.netmask, 16) < 0)); +} + #ifdef WIN32 std::string NetworkErrorString(int err) { diff --git a/src/netbase.h b/src/netbase.h index 6d2ca4afb2..6f8882b852 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -100,6 +100,8 @@ class CNetAddr inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(FLATDATA(ip)); } + + friend class CSubNet; }; class CSubNet @@ -116,6 +118,9 @@ class CSubNet CSubNet(); explicit CSubNet(const std::string &strSubnet, bool fAllowLookup = false); + //constructor for single ip subnet (<ipv4>/32 or <ipv6>/128) + explicit CSubNet(const CNetAddr &addr); + bool Match(const CNetAddr &addr) const; std::string ToString() const; @@ -123,6 +128,16 @@ class CSubNet friend bool operator==(const CSubNet& a, const CSubNet& b); friend bool operator!=(const CSubNet& a, const CSubNet& b); + friend bool operator<(const CSubNet& a, const CSubNet& b); + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(network); + READWRITE(FLATDATA(netmask)); + READWRITE(FLATDATA(valid)); + } }; /** A combination of a network address (CNetAddr) and a (TCP) port */ diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp new file mode 100644 index 0000000000..ffe31d1942 --- /dev/null +++ b/src/policy/fees.cpp @@ -0,0 +1,530 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// 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. + +#include "policy/fees.h" + +#include "amount.h" +#include "primitives/transaction.h" +#include "streams.h" +#include "txmempool.h" +#include "util.h" + +void TxConfirmStats::Initialize(std::vector<double>& defaultBuckets, + unsigned int maxConfirms, double _decay, std::string _dataTypeString) +{ + decay = _decay; + dataTypeString = _dataTypeString; + for (unsigned int i = 0; i < defaultBuckets.size(); i++) { + buckets.push_back(defaultBuckets[i]); + bucketMap[defaultBuckets[i]] = i; + } + confAvg.resize(maxConfirms); + curBlockConf.resize(maxConfirms); + unconfTxs.resize(maxConfirms); + for (unsigned int i = 0; i < maxConfirms; i++) { + confAvg[i].resize(buckets.size()); + curBlockConf[i].resize(buckets.size()); + unconfTxs[i].resize(buckets.size()); + } + + oldUnconfTxs.resize(buckets.size()); + curBlockTxCt.resize(buckets.size()); + txCtAvg.resize(buckets.size()); + curBlockVal.resize(buckets.size()); + avg.resize(buckets.size()); +} + +// Zero out the data for the current block +void TxConfirmStats::ClearCurrent(unsigned int nBlockHeight) +{ + for (unsigned int j = 0; j < buckets.size(); j++) { + oldUnconfTxs[j] += unconfTxs[nBlockHeight%unconfTxs.size()][j]; + unconfTxs[nBlockHeight%unconfTxs.size()][j] = 0; + for (unsigned int i = 0; i < curBlockConf.size(); i++) + curBlockConf[i][j] = 0; + curBlockTxCt[j] = 0; + curBlockVal[j] = 0; + } +} + + +void TxConfirmStats::Record(int blocksToConfirm, double val) +{ + // blocksToConfirm is 1-based + if (blocksToConfirm < 1) + return; + unsigned int bucketindex = bucketMap.lower_bound(val)->second; + for (size_t i = blocksToConfirm; i <= curBlockConf.size(); i++) { + curBlockConf[i - 1][bucketindex]++; + } + curBlockTxCt[bucketindex]++; + curBlockVal[bucketindex] += val; +} + +void TxConfirmStats::UpdateMovingAverages() +{ + for (unsigned int j = 0; j < buckets.size(); j++) { + for (unsigned int i = 0; i < confAvg.size(); i++) + confAvg[i][j] = confAvg[i][j] * decay + curBlockConf[i][j]; + avg[j] = avg[j] * decay + curBlockVal[j]; + txCtAvg[j] = txCtAvg[j] * decay + curBlockTxCt[j]; + } +} + +// returns -1 on error conditions +double TxConfirmStats::EstimateMedianVal(int confTarget, double sufficientTxVal, + double successBreakPoint, bool requireGreater, + unsigned int nBlockHeight) +{ + // Counters for a bucket (or range of buckets) + double nConf = 0; // Number of tx's confirmed within the confTarget + double totalNum = 0; // Total number of tx's that were ever confirmed + int extraNum = 0; // Number of tx's still in mempool for confTarget or longer + + 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 + // 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; + int step = requireGreater ? -1 : 1; + + // We'll combine buckets until we have enough samples. + // The near and far variables will define the range we've combined + // The best variables are the last range we saw which still had a high + // enough confirmation rate to count as success. + // The cur variables are the current range we're counting. + unsigned int curNearBucket = startbucket; + unsigned int bestNearBucket = startbucket; + unsigned int curFarBucket = startbucket; + unsigned int bestFarBucket = startbucket; + + bool foundAnswer = false; + unsigned int bins = unconfTxs.size(); + + // Start counting from highest(default) or lowest fee/pri transactions + for (int bucket = startbucket; bucket >= 0 && bucket <= maxbucketindex; bucket += step) { + curFarBucket = bucket; + nConf += confAvg[confTarget - 1][bucket]; + totalNum += txCtAvg[bucket]; + for (unsigned int confct = confTarget; confct < GetMaxConfirms(); confct++) + extraNum += unconfTxs[(nBlockHeight - confct)%bins][bucket]; + extraNum += oldUnconfTxs[bucket]; + // If we have enough transaction data points in this range of buckets, + // we can test for success + // (Only count the confirmed data points, so that each confirmation count + // will be looking at the same amount of data and same bucket breaks) + if (totalNum >= sufficientTxVal / (1 - decay)) { + double curPct = nConf / (totalNum + extraNum); + + // Check to see if we are no longer getting confirmed at the success rate + if (requireGreater && curPct < successBreakPoint) + break; + if (!requireGreater && curPct > successBreakPoint) + break; + + // Otherwise update the cumulative stats, and the bucket variables + // and reset the counters + else { + foundAnswer = true; + nConf = 0; + totalNum = 0; + extraNum = 0; + bestNearBucket = curNearBucket; + bestFarBucket = curFarBucket; + curNearBucket = bucket + step; + } + } + } + + double median = -1; + double txSum = 0; + + // Calculate the "average" fee of the best bucket range that met success conditions + // Find the bucket with the median transaction and then report the average fee from that bucket + // This is a compromise between finding the median which we can't since we don't save all tx's + // and reporting the average which is less accurate + unsigned int minBucket = bestNearBucket < bestFarBucket ? bestNearBucket : bestFarBucket; + unsigned int maxBucket = bestNearBucket > bestFarBucket ? bestNearBucket : bestFarBucket; + for (unsigned int j = minBucket; j <= maxBucket; j++) { + txSum += txCtAvg[j]; + } + if (foundAnswer && txSum != 0) { + txSum = txSum / 2; + for (unsigned int j = minBucket; j <= maxBucket; j++) { + if (txCtAvg[j] < txSum) + txSum -= txCtAvg[j]; + else { // we're in the right bucket + median = avg[j] / txCtAvg[j]; + break; + } + } + } + + LogPrint("estimatefee", "%3d: For conf success %s %4.2f need %s %s: %12.5g from buckets %8g - %8g Cur Bucket stats %6.2f%% %8.1f/(%.1f+%d mempool)\n", + confTarget, requireGreater ? ">" : "<", successBreakPoint, dataTypeString, + requireGreater ? ">" : "<", median, buckets[minBucket], buckets[maxBucket], + 100 * nConf / (totalNum + extraNum), nConf, totalNum, extraNum); + + return median; +} + +void TxConfirmStats::Write(CAutoFile& fileout) +{ + fileout << decay; + fileout << buckets; + fileout << avg; + fileout << txCtAvg; + fileout << confAvg; +} + +void TxConfirmStats::Read(CAutoFile& filein) +{ + // Read data file into temporary variables and do some very basic sanity checking + std::vector<double> fileBuckets; + std::vector<double> fileAvg; + std::vector<std::vector<double> > fileConfAvg; + std::vector<double> fileTxCtAvg; + double fileDecay; + size_t maxConfirms; + size_t numBuckets; + + filein >> fileDecay; + if (fileDecay <= 0 || fileDecay >= 1) + throw std::runtime_error("Corrupt estimates file. Decay must be between 0 and 1 (non-inclusive)"); + filein >> fileBuckets; + numBuckets = fileBuckets.size(); + if (numBuckets <= 1 || numBuckets > 1000) + throw std::runtime_error("Corrupt estimates file. Must have between 2 and 1000 fee/pri buckets"); + filein >> fileAvg; + if (fileAvg.size() != numBuckets) + throw std::runtime_error("Corrupt estimates file. Mismatch in fee/pri average bucket count"); + filein >> fileTxCtAvg; + if (fileTxCtAvg.size() != numBuckets) + throw std::runtime_error("Corrupt estimates file. Mismatch in tx count bucket count"); + filein >> fileConfAvg; + maxConfirms = fileConfAvg.size(); + if (maxConfirms <= 0 || maxConfirms > 6 * 24 * 7) // one week + throw std::runtime_error("Corrupt estimates file. Must maintain estimates for between 1 and 1008 (one week) confirms"); + for (unsigned int i = 0; i < maxConfirms; i++) { + if (fileConfAvg[i].size() != numBuckets) + throw std::runtime_error("Corrupt estimates file. Mismatch in fee/pri conf average bucket count"); + } + // Now that we've processed the entire fee estimate data file and not + // thrown any errors, we can copy it to our data structures + decay = fileDecay; + buckets = fileBuckets; + avg = fileAvg; + confAvg = fileConfAvg; + txCtAvg = fileTxCtAvg; + bucketMap.clear(); + + // Resize the current block variables which aren't stored in the data file + // to match the number of confirms and buckets + curBlockConf.resize(maxConfirms); + for (unsigned int i = 0; i < maxConfirms; i++) { + curBlockConf[i].resize(buckets.size()); + } + curBlockTxCt.resize(buckets.size()); + curBlockVal.resize(buckets.size()); + + unconfTxs.resize(maxConfirms); + for (unsigned int i = 0; i < maxConfirms; i++) { + unconfTxs[i].resize(buckets.size()); + } + oldUnconfTxs.resize(buckets.size()); + + for (unsigned int i = 0; i < buckets.size(); i++) + bucketMap[buckets[i]] = i; + + LogPrint("estimatefee", "Reading estimates: %u %s buckets counting confirms up to %u blocks\n", + numBuckets, dataTypeString, maxConfirms); +} + +unsigned int TxConfirmStats::NewTx(unsigned int nBlockHeight, double val) +{ + unsigned int bucketindex = bucketMap.lower_bound(val)->second; + unsigned int blockIndex = nBlockHeight % unconfTxs.size(); + unconfTxs[blockIndex][bucketindex]++; + LogPrint("estimatefee", "adding to %s", dataTypeString); + return bucketindex; +} + +void TxConfirmStats::removeTx(unsigned int entryHeight, unsigned int nBestSeenHeight, unsigned int bucketindex) +{ + //nBestSeenHeight is not updated yet for the new block + int blocksAgo = nBestSeenHeight - entryHeight; + if (nBestSeenHeight == 0) // the BlockPolicyEstimator hasn't seen any blocks yet + blocksAgo = 0; + if (blocksAgo < 0) { + LogPrint("estimatefee", "Blockpolicy error, blocks ago is negative for mempool tx\n"); + return; //This can't happen because we call this with our best seen height, no entries can have higher + } + + if (blocksAgo >= (int)unconfTxs.size()) { + if (oldUnconfTxs[bucketindex] > 0) + oldUnconfTxs[bucketindex]--; + else + LogPrint("estimatefee", "Blockpolicy error, mempool tx removed from >25 blocks,bucketIndex=%u already\n", + bucketindex); + } + else { + unsigned int blockIndex = entryHeight % unconfTxs.size(); + if (unconfTxs[blockIndex][bucketindex] > 0) + unconfTxs[blockIndex][bucketindex]--; + else + LogPrint("estimatefee", "Blockpolicy error, mempool tx removed from blockIndex=%u,bucketIndex=%u already\n", + blockIndex, bucketindex); + } +} + +void CBlockPolicyEstimator::removeTx(uint256 hash) +{ + std::map<uint256, TxStatsInfo>::iterator pos = mapMemPoolTxs.find(hash); + if (pos == mapMemPoolTxs.end()) { + LogPrint("estimatefee", "Blockpolicy error mempool tx %s not found for removeTx\n", + hash.ToString().c_str()); + return; + } + TxConfirmStats *stats = pos->second.stats; + unsigned int entryHeight = pos->second.blockHeight; + unsigned int bucketIndex = pos->second.bucketIndex; + + if (stats != NULL) + stats->removeTx(entryHeight, nBestSeenHeight, bucketIndex); + mapMemPoolTxs.erase(hash); +} + +CBlockPolicyEstimator::CBlockPolicyEstimator(const CFeeRate& _minRelayFee) + : nBestSeenHeight(0) +{ + minTrackedFee = _minRelayFee < CFeeRate(MIN_FEERATE) ? CFeeRate(MIN_FEERATE) : _minRelayFee; + std::vector<double> vfeelist; + for (double bucketBoundary = minTrackedFee.GetFeePerK(); bucketBoundary <= MAX_FEERATE; bucketBoundary *= FEE_SPACING) { + vfeelist.push_back(bucketBoundary); + } + vfeelist.push_back(INF_FEERATE); + feeStats.Initialize(vfeelist, MAX_BLOCK_CONFIRMS, DEFAULT_DECAY, "FeeRate"); + + minTrackedPriority = AllowFreeThreshold() < MIN_PRIORITY ? MIN_PRIORITY : AllowFreeThreshold(); + std::vector<double> vprilist; + for (double bucketBoundary = minTrackedPriority; bucketBoundary <= MAX_PRIORITY; bucketBoundary *= PRI_SPACING) { + vprilist.push_back(bucketBoundary); + } + vprilist.push_back(INF_PRIORITY); + priStats.Initialize(vprilist, MAX_BLOCK_CONFIRMS, DEFAULT_DECAY, "Priority"); + + feeUnlikely = CFeeRate(0); + feeLikely = CFeeRate(INF_FEERATE); + priUnlikely = 0; + priLikely = INF_PRIORITY; +} + +bool CBlockPolicyEstimator::isFeeDataPoint(const CFeeRate &fee, double pri) +{ + if ((pri < minTrackedPriority && fee >= minTrackedFee) || + (pri < priUnlikely && fee > feeLikely)) { + return true; + } + return false; +} + +bool CBlockPolicyEstimator::isPriDataPoint(const CFeeRate &fee, double pri) +{ + if ((fee < minTrackedFee && pri >= minTrackedPriority) || + (fee < feeUnlikely && pri > priLikely)) { + return true; + } + return false; +} + +void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, bool fCurrentEstimate) +{ + unsigned int txHeight = entry.GetHeight(); + uint256 hash = entry.GetTx().GetHash(); + if (mapMemPoolTxs[hash].stats != NULL) { + LogPrint("estimatefee", "Blockpolicy error mempool tx %s already being tracked\n", + hash.ToString().c_str()); + return; + } + + if (txHeight < nBestSeenHeight) { + // Ignore side chains and re-orgs; assuming they are random they don't + // affect the estimate. We'll potentially double count transactions in 1-block reorgs. + return; + } + + // Only want to be updating estimates when our blockchain is synced, + // otherwise we'll miscalculate how many blocks its taking to get included. + if (!fCurrentEstimate) + return; + + if (!entry.WasClearAtEntry()) { + // This transaction depends on other transactions in the mempool to + // be included in a block before it will be able to be included, so + // we shouldn't include it in our calculations + return; + } + + // Fees are stored and reported as BTC-per-kb: + CFeeRate feeRate(entry.GetFee(), entry.GetTxSize()); + + // Want the priority of the tx at confirmation. However we don't know + // what that will be and its too hard to continue updating it + // so use starting priority as a proxy + double curPri = entry.GetPriority(txHeight); + mapMemPoolTxs[hash].blockHeight = txHeight; + + LogPrint("estimatefee", "Blockpolicy mempool tx %s ", hash.ToString().substr(0,10)); + // Record this as a priority estimate + if (entry.GetFee() == 0 || isPriDataPoint(feeRate, curPri)) { + mapMemPoolTxs[hash].stats = &priStats; + mapMemPoolTxs[hash].bucketIndex = priStats.NewTx(txHeight, curPri); + } + // Record this as a fee estimate + else if (isFeeDataPoint(feeRate, curPri)) { + mapMemPoolTxs[hash].stats = &feeStats; + mapMemPoolTxs[hash].bucketIndex = feeStats.NewTx(txHeight, (double)feeRate.GetFeePerK()); + } + else { + LogPrint("estimatefee", "not adding"); + } + LogPrint("estimatefee", "\n"); +} + +void CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry& entry) +{ + if (!entry.WasClearAtEntry()) { + // This transaction depended on other transactions in the mempool to + // be included in a block before it was able to be included, so + // we shouldn't include it in our calculations + return; + } + + // How many blocks did it take for miners to include this transaction? + // blocksToConfirm is 1-based, so a transaction included in the earliest + // possible block has confirmation count of 1 + int blocksToConfirm = nBlockHeight - entry.GetHeight(); + if (blocksToConfirm <= 0) { + // This can't happen because we don't process transactions from a block with a height + // lower than our greatest seen height + LogPrint("estimatefee", "Blockpolicy error Transaction had negative blocksToConfirm\n"); + return; + } + + // Fees are stored and reported as BTC-per-kb: + CFeeRate feeRate(entry.GetFee(), entry.GetTxSize()); + + // Want the priority of the tx at confirmation. The priority when it + // entered the mempool could easily be very small and change quickly + double curPri = entry.GetPriority(nBlockHeight); + + // Record this as a priority estimate + if (entry.GetFee() == 0 || isPriDataPoint(feeRate, curPri)) { + priStats.Record(blocksToConfirm, curPri); + } + // Record this as a fee estimate + else if (isFeeDataPoint(feeRate, curPri)) { + feeStats.Record(blocksToConfirm, (double)feeRate.GetFeePerK()); + } +} + +void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight, + std::vector<CTxMemPoolEntry>& entries, bool fCurrentEstimate) +{ + if (nBlockHeight <= nBestSeenHeight) { + // Ignore side chains and re-orgs; assuming they are random + // they don't affect the estimate. + // And if an attacker can re-org the chain at will, then + // you've got much bigger problems than "attacker can influence + // transaction fees." + return; + } + nBestSeenHeight = nBlockHeight; + + // Only want to be updating estimates when our blockchain is synced, + // otherwise we'll miscalculate how many blocks its taking to get included. + if (!fCurrentEstimate) + return; + + // Update the dynamic cutoffs + // a fee/priority is "likely" the reason your tx was included in a block if >85% of such tx's + // were confirmed in 2 blocks and is "unlikely" if <50% were confirmed in 10 blocks + LogPrint("estimatefee", "Blockpolicy recalculating dynamic cutoffs:\n"); + priLikely = priStats.EstimateMedianVal(2, SUFFICIENT_PRITXS, MIN_SUCCESS_PCT, true, nBlockHeight); + if (priLikely == -1) + priLikely = INF_PRIORITY; + + double feeLikelyEst = feeStats.EstimateMedianVal(2, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBlockHeight); + if (feeLikelyEst == -1) + feeLikely = CFeeRate(INF_FEERATE); + else + feeLikely = CFeeRate(feeLikelyEst); + + priUnlikely = priStats.EstimateMedianVal(10, SUFFICIENT_PRITXS, UNLIKELY_PCT, false, nBlockHeight); + if (priUnlikely == -1) + priUnlikely = 0; + + double feeUnlikelyEst = feeStats.EstimateMedianVal(10, SUFFICIENT_FEETXS, UNLIKELY_PCT, false, nBlockHeight); + if (feeUnlikelyEst == -1) + feeUnlikely = CFeeRate(0); + else + feeUnlikely = CFeeRate(feeUnlikelyEst); + + // Clear the current block states + feeStats.ClearCurrent(nBlockHeight); + priStats.ClearCurrent(nBlockHeight); + + // Repopulate the current block states + for (unsigned int i = 0; i < entries.size(); i++) + processBlockTx(nBlockHeight, entries[i]); + + // Update all exponential averages with the current block states + feeStats.UpdateMovingAverages(); + priStats.UpdateMovingAverages(); + + LogPrint("estimatefee", "Blockpolicy after updating estimates for %u confirmed entries, new mempool map size %u\n", + entries.size(), mapMemPoolTxs.size()); +} + +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()) + return CFeeRate(0); + + double median = feeStats.EstimateMedianVal(confTarget, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBestSeenHeight); + + if (median < 0) + return CFeeRate(0); + + return CFeeRate(median); +} + +double CBlockPolicyEstimator::estimatePriority(int confTarget) +{ + // Return failure if trying to analyze a target we're not tracking + if (confTarget <= 0 || (unsigned int)confTarget > priStats.GetMaxConfirms()) + return -1; + + return priStats.EstimateMedianVal(confTarget, SUFFICIENT_PRITXS, MIN_SUCCESS_PCT, true, nBestSeenHeight); +} + +void CBlockPolicyEstimator::Write(CAutoFile& fileout) +{ + fileout << nBestSeenHeight; + feeStats.Write(fileout); + priStats.Write(fileout); +} + +void CBlockPolicyEstimator::Read(CAutoFile& filein) +{ + int nFileBestSeenHeight; + filein >> nFileBestSeenHeight; + feeStats.Read(filein); + priStats.Read(filein); + nBestSeenHeight = nFileBestSeenHeight; +} diff --git a/src/policy/fees.h b/src/policy/fees.h new file mode 100644 index 0000000000..15577d128a --- /dev/null +++ b/src/policy/fees.h @@ -0,0 +1,276 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// 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. +#ifndef BITCOIN_POLICYESTIMATOR_H +#define BITCOIN_POLICYESTIMATOR_H + +#include "amount.h" +#include "uint256.h" + +#include <map> +#include <string> +#include <vector> + +class CAutoFile; +class CFeeRate; +class CTxMemPoolEntry; + +/** \class CBlockPolicyEstimator + * The BlockPolicyEstimator is used for estimating the fee or priority needed + * for a transaction to be included in a block within a certain number of + * blocks. + * + * At a high level the algorithm works by grouping transactions into buckets + * based on having similar priorities or fees and then tracking how long it + * takes transactions in the various buckets to be mined. It operates under + * the assumption that in general transactions of higher fee/priority will be + * 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 + * 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 + * bucket will give you an indication of the lowest fee you can put on a + * transaction and still have a sufficiently high chance of being confirmed + * within your desired 5 blocks. + * + * When a transaction enters the mempool or is included within a block we + * decide whether it can be used as a data point for fee estimation, priority + * estimation or neither. If the value of exactly one of those properties was + * below the required minimum it can be used to estimate the other. In + * addition, if a priori our estimation code would indicate that the + * transaction would be much more quickly included in a block because of one + * of the properties compared to the other, we can also decide to use it as + * an estimate for that property. + * + * Here is a brief description of the implementation for fee estimation. + * When a transaction that counts for fee estimation enters the mempool, we + * track the height of the block chain at entry. Whenever a block comes in, + * we count the number of transactions in each bucket and the total amount of fee + * paid in each bucket. Then we calculate how many blocks Y it took each + * transaction to be mined and we track an array of counters in each bucket + * for how long it to took transactions to get confirmed from 1 to a max of 25 + * and we increment all the counters from Y up to 25. This is because for any + * number Z>=Y the transaction was successfully mined within Z blocks. We + * want to save a history of this information, so at any time we have a + * counter of the total number of transactions that happened in a given fee + * bucket and the total number that were confirmed in each number 1-25 blocks + * or less for any bucket. We save this history by keeping an exponentially + * decaying moving average of each one of these stats. Furthermore we also + * keep track of the number unmined (in mempool) transactions in each bucket + * and for how many blocks they have been outstanding and use that to increase + * the number of transactions we've seen in that fee bucket when calculating + * an estimate for any number of confirmations below the number of blocks + * they've been outstanding. + */ + +/** + * We will instantiate two instances of this class, one to track transactions + * that were included in a block due to fee, and one for tx's included due to + * priority. We will lump transactions into a bucket according to their approximate + * fee or priority and then track how long it took for those txs to be included in a block + * + * The tracking of unconfirmed (mempool) transactions is completely independent of the + * historical tracking of transactions that have been confirmed in a block. + */ +class TxConfirmStats +{ +private: + //Define the buckets we will group transactions into (both fee buckets and priority buckets) + std::vector<double> buckets; // The upper-bound of the range for the bucket (inclusive) + std::map<double, unsigned int> bucketMap; // Map of bucket upper-bound to index into all vectors by bucket + + // For each bucket X: + // Count the total # of txs in each bucket + // Track the historical moving average of this total over blocks + std::vector<double> txCtAvg; + // and calcuate the total for the current block to update the moving average + std::vector<int> 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<std::vector<double> > confAvg; // confAvg[Y][X] + // and calcuate the totals for the current block to update the moving averages + std::vector<std::vector<int> > curBlockConf; // curBlockConf[Y][X] + + // Sum the total priority/fee of all tx's in each bucket + // Track the historical moving average of this total over blocks + std::vector<double> avg; + // and calculate the total for the current block to update the moving average + std::vector<double> curBlockVal; + + // Combine the conf counts with tx counts to calculate the confirmation % for each Y,X + // Combine the total value with the tx counts to calculate the avg fee/priority per bucket + + std::string dataTypeString; + double decay; + + // Mempool counts of outstanding transactions + // For each bucket X, track the number of transactions in the mempool + // that are unconfirmed for each possible confirmation value Y + std::vector<std::vector<int> > unconfTxs; //unconfTxs[Y][X] + // transactions still unconfirmed after MAX_CONFIRMS for each bucket + std::vector<int> oldUnconfTxs; + +public: + /** + * Initialize the data structures. This is called by BlockPolicyEstimator's + * constructor with default values. + * @param defaultBuckets contains the upper limits for the bucket boundaries + * @param maxConfirms max number of confirms to track + * @param decay how much to decay the historical moving average per block + * @param dataTypeString for logging purposes + */ + void Initialize(std::vector<double>& defaultBuckets, unsigned int maxConfirms, double decay, std::string dataTypeString); + + /** Clear the state of the curBlock variables to start counting for the new block */ + void ClearCurrent(unsigned int nBlockHeight); + + /** + * Record a new transaction data point in the current block stats + * @param blocksToConfirm the number of blocks it took this transaction to confirm + * @param val either the fee or the priority when entered of the transaction + * @warning blocksToConfirm is 1-based and has to be >= 1 + */ + void Record(int blocksToConfirm, double val); + + /** Record a new transaction entering the mempool*/ + unsigned int NewTx(unsigned int nBlockHeight, double val); + + /** Remove a transaction from mempool tracking stats*/ + void removeTx(unsigned int entryHeight, unsigned int nBestSeenHeight, + unsigned int bucketIndex); + + /** Update our estimates by decaying our historical moving average and updating + with the data gathered from the current block */ + void UpdateMovingAverages(); + + /** + * Calculate a fee or priority estimate. Find the lowest value bucket (or range of buckets + * to make sure we have enough data points) whose transactions still have sufficient likelihood + * of being confirmed within the target number of confirmations + * @param confTarget target number of confirmations + * @param sufficientTxVal required average number of transactions per block in a bucket range + * @param minSuccess the success probability we require + * @param requireGreater return the lowest fee/pri such that all higher values pass minSuccess OR + * return the highest fee/pri such that all lower values fail minSuccess + * @param nBlockHeight the current block height + */ + double EstimateMedianVal(int confTarget, double sufficientTxVal, + double minSuccess, bool requireGreater, unsigned int nBlockHeight); + + /** Return the max number of confirms we're tracking */ + unsigned int GetMaxConfirms() { return confAvg.size(); } + + /** Write state of estimation data to a file*/ + void Write(CAutoFile& fileout); + + /** + * Read saved state of estimation data from a file and replace all internal data structures and + * variables with this state. + */ + void Read(CAutoFile& filein); +}; + + + +/** Track confirm delays up to 25 blocks, can't estimate beyond that */ +static const unsigned int MAX_BLOCK_CONFIRMS = 25; + +/** Decay of .998 is a half-life of 346 blocks or about 2.4 days */ +static const double DEFAULT_DECAY = .998; + +/** Require greater than 85% of X fee transactions to be confirmed within Y blocks for X to be big enough */ +static const double MIN_SUCCESS_PCT = .85; +static const double UNLIKELY_PCT = .5; + +/** Require an avg of 1 tx in the combined fee bucket per block to have stat significance */ +static const double SUFFICIENT_FEETXS = 1; + +/** Require only an avg of 1 tx every 5 blocks in the combined pri bucket (way less pri txs) */ +static const double SUFFICIENT_PRITXS = .2; + +// Minimum and Maximum values for tracking fees and priorities +static const double MIN_FEERATE = 10; +static const double MAX_FEERATE = 1e7; +static const double INF_FEERATE = MAX_MONEY; +static const double MIN_PRIORITY = 10; +static const double MAX_PRIORITY = 1e16; +static const double INF_PRIORITY = 1e9 * MAX_MONEY; + +// We have to lump transactions into buckets based on fee or priority, but we want to be able +// to give accurate estimates over a large range of potential fees and priorities +// Therefore it makes sense to exponentially space the buckets +/** Spacing of FeeRate buckets */ +static const double FEE_SPACING = 1.1; + +/** Spacing of Priority buckets */ +static const double PRI_SPACING = 2; + +/** + * We want to be able to estimate fees or priorities that are needed on tx's to be included in + * a certain number of blocks. Every time a block is added to the best chain, this class records + * stats on the transactions included in that block + */ +class CBlockPolicyEstimator +{ +public: + /** Create new BlockPolicyEstimator and initialize stats tracking classes with default values */ + CBlockPolicyEstimator(const CFeeRate& minRelayFee); + + /** Process all the transactions that have been included in a block */ + void processBlock(unsigned int nBlockHeight, + std::vector<CTxMemPoolEntry>& entries, bool fCurrentEstimate); + + /** Process a transaction confirmed in a block*/ + void processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry& entry); + + /** Process a transaction accepted to the mempool*/ + void processTransaction(const CTxMemPoolEntry& entry, bool fCurrentEstimate); + + /** Remove a transaction from the mempool tracking stats*/ + void removeTx(uint256 hash); + + /** Is this transaction likely included in a block because of its fee?*/ + bool isFeeDataPoint(const CFeeRate &fee, double pri); + + /** Is this transaction likely included in a block because of its priority?*/ + bool isPriDataPoint(const CFeeRate &fee, double pri); + + /** Return a fee estimate */ + CFeeRate estimateFee(int confTarget); + + /** Return a priority estimate */ + double estimatePriority(int confTarget); + + /** Write estimation data to a file */ + void Write(CAutoFile& fileout); + + /** Read estimation data from a file */ + void Read(CAutoFile& filein); + +private: + CFeeRate minTrackedFee; //! Passed to constructor to avoid dependency on main + double minTrackedPriority; //! Set to AllowFreeThreshold + unsigned int nBestSeenHeight; + struct TxStatsInfo + { + TxConfirmStats *stats; + unsigned int blockHeight; + unsigned int bucketIndex; + TxStatsInfo() : stats(NULL), blockHeight(0), bucketIndex(0) {} + }; + + // map of txids to information about that transaction + std::map<uint256, TxStatsInfo> mapMemPoolTxs; + + /** Classes to track historical data on transaction confirmations */ + TxConfirmStats feeStats, priStats; + + /** Breakpoints to help determine whether a transaction was confirmed by priority or Fee */ + CFeeRate feeLikely, feeUnlikely; + double priLikely, priUnlikely; +}; +#endif /*BITCOIN_POLICYESTIMATOR_H */ diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp new file mode 100644 index 0000000000..169fef4af4 --- /dev/null +++ b/src/policy/policy.cpp @@ -0,0 +1,178 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +// NOTE: This file is intended to be customised by the end user, and includes only local node policy logic + +#include "policy/policy.h" + +#include "main.h" +#include "tinyformat.h" +#include "util.h" +#include "utilstrencodings.h" + +#include <boost/foreach.hpp> + + /** + * Check transaction inputs to mitigate two + * potential denial-of-service attacks: + * + * 1. scriptSigs with extra data stuffed into them, + * not consumed by scriptPubKey (or P2SH script) + * 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 + * script can be anything; an attacker could use a very + * expensive-to-check-upon-redemption script like: + * DUP CHECKSIG DROP ... repeated 100 times... OP_1 + */ + +bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) +{ + std::vector<std::vector<unsigned char> > vSolutions; + if (!Solver(scriptPubKey, whichType, vSolutions)) + return false; + + if (whichType == TX_MULTISIG) + { + unsigned char m = vSolutions.front()[0]; + unsigned char n = vSolutions.back()[0]; + // Support up to x-of-3 multisig txns as standard + if (n < 1 || n > 3) + return false; + if (m < 1 || m > n) + return false; + } + + return whichType != TX_NONSTANDARD; +} + +bool IsStandardTx(const CTransaction& tx, std::string& reason) +{ + if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) { + reason = "version"; + return false; + } + + // Extremely large transactions with lots of inputs can cost the network + // 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) { + reason = "tx-size"; + return false; + } + + 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 + // 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) + if (txin.scriptSig.size() > 1650) { + reason = "scriptsig-size"; + return false; + } + if (!txin.scriptSig.IsPushOnly()) { + reason = "scriptsig-not-pushonly"; + return false; + } + } + + unsigned int nDataOut = 0; + txnouttype whichType; + BOOST_FOREACH(const CTxOut& txout, tx.vout) { + if (!::IsStandard(txout.scriptPubKey, whichType)) { + reason = "scriptpubkey"; + return false; + } + + if (whichType == TX_NULL_DATA) + nDataOut++; + else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) { + reason = "bare-multisig"; + return false; + } else if (txout.IsDust(::minRelayTxFee)) { + reason = "dust"; + return false; + } + } + + // only one OP_RETURN txout is permitted + if (nDataOut > 1) { + reason = "multi-op-return"; + return false; + } + + return true; +} + +bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) +{ + if (tx.IsCoinBase()) + return true; // Coinbases don't use vin normally + + for (unsigned int i = 0; i < tx.vin.size(); i++) + { + const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]); + + std::vector<std::vector<unsigned char> > vSolutions; + txnouttype whichType; + // get the scriptPubKey corresponding to this input: + 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<std::vector<unsigned char> > stack; + if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker())) + return false; + + if (whichType == TX_SCRIPTHASH) + { + if (stack.empty()) + return false; + CScript subscript(stack.back().begin(), stack.back().end()); + std::vector<std::vector<unsigned char> > 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 (stack.size() != (unsigned int)nArgsExpected) + return false; + } + + return true; +} diff --git a/src/policy/policy.h b/src/policy/policy.h new file mode 100644 index 0000000000..1551aecde8 --- /dev/null +++ b/src/policy/policy.h @@ -0,0 +1,58 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 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_H +#define BITCOIN_POLICY_H + +#include "consensus/consensus.h" +#include "script/interpreter.h" +#include "script/standard.h" + +#include <string> + +class CCoinsViewCache; + +/** Default for -blockmaxsize and -blockminsize, which control the range of sizes 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 = 50000; +/** The maximum size for transactions we're willing to relay/mine */ +static const unsigned int MAX_STANDARD_TX_SIZE = 100000; +/** 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; +/** + * Standard script verification flags that standard transactions will comply + * with. However scripts violating these flags may still be present in valid + * blocks and we must accept those blocks. + */ +static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS | + SCRIPT_VERIFY_DERSIG | + SCRIPT_VERIFY_STRICTENC | + SCRIPT_VERIFY_MINIMALDATA | + SCRIPT_VERIFY_NULLDUMMY | + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS | + SCRIPT_VERIFY_CLEANSTACK | + SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; + +/** 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; + +bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType); + /** + * Check for standard transaction types + * @return True if all outputs (scriptPubKeys) use only standard transaction forms + */ +bool IsStandardTx(const CTransaction& tx, std::string& reason); + /** + * Check for standard transaction types + * @param[in] mapInputs Map of previous transactions that have outputs we're spending + * @return True if all inputs (scriptSigs) use only standard transaction forms + */ +bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs); + +#endif // BITCOIN_POLICY_H diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 5b9c13d870..7a58074d24 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -15,7 +15,7 @@ uint256 CBlockHeader::GetHash() const return SerializeHash(*this); } -uint256 CBlock::BuildMerkleTree(bool* fMutated) const +uint256 CBlock::ComputeMerkleRoot(bool* fMutated) const { /* WARNING! If you're reading this because you're learning about crypto and/or designing a new system that will use merkle trees, keep in mind @@ -52,7 +52,7 @@ uint256 CBlock::BuildMerkleTree(bool* fMutated) const known ways of changing the transactions without affecting the merkle root. */ - vMerkleTree.clear(); + std::vector<uint256> vMerkleTree; vMerkleTree.reserve(vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes. for (std::vector<CTransaction>::const_iterator it(vtx.begin()); it != vtx.end(); ++it) vMerkleTree.push_back(it->GetHash()); @@ -78,37 +78,6 @@ uint256 CBlock::BuildMerkleTree(bool* fMutated) const return (vMerkleTree.empty() ? uint256() : vMerkleTree.back()); } -std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const -{ - if (vMerkleTree.empty()) - BuildMerkleTree(); - std::vector<uint256> vMerkleBranch; - int j = 0; - for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) - { - int i = std::min(nIndex^1, nSize-1); - vMerkleBranch.push_back(vMerkleTree[j+i]); - nIndex >>= 1; - j += nSize; - } - return vMerkleBranch; -} - -uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex) -{ - if (nIndex == -1) - return uint256(); - for (std::vector<uint256>::const_iterator it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it) - { - if (nIndex & 1) - hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash)); - else - hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it)); - nIndex >>= 1; - } - return hash; -} - std::string CBlock::ToString() const { std::stringstream s; @@ -123,9 +92,5 @@ std::string CBlock::ToString() const { s << " " << vtx[i].ToString() << "\n"; } - s << " vMerkleTree: "; - for (unsigned int i = 0; i < vMerkleTree.size(); i++) - s << " " << vMerkleTree[i].ToString(); - s << "\n"; return s.str(); } diff --git a/src/primitives/block.h b/src/primitives/block.h index 59f46deb1c..86106098f5 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -78,7 +78,7 @@ public: std::vector<CTransaction> vtx; // memory only - mutable std::vector<uint256> vMerkleTree; + mutable bool fChecked; CBlock() { @@ -103,7 +103,7 @@ public: { CBlockHeader::SetNull(); vtx.clear(); - vMerkleTree.clear(); + fChecked = false; } CBlockHeader GetBlockHeader() const @@ -118,14 +118,12 @@ public: return block; } - // Build the in-memory merkle tree for this block and return the merkle root. + // Build the merkle tree for this block and return the merkle root. // If non-NULL, *mutated is set to whether mutation was detected in the merkle // tree (a duplication of transactions in the block leading to an identical // merkle root). - uint256 BuildMerkleTree(bool* mutated = NULL) const; + uint256 ComputeMerkleRoot(bool* mutated = NULL) const; - std::vector<uint256> GetMerkleBranch(int nIndex) const; - static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex); std::string ToString() const; }; diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 606dbea798..46d3cbbe2e 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -36,7 +36,7 @@ std::string CTxIn::ToString() const if (prevout.IsNull()) str += strprintf(", coinbase %s", HexStr(scriptSig)); else - str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24)); + str += strprintf(", scriptSig=%s", HexStr(scriptSig).substr(0, 24)); if (nSequence != std::numeric_limits<unsigned int>::max()) str += strprintf(", nSequence=%u", nSequence); str += ")"; @@ -56,7 +56,7 @@ uint256 CTxOut::GetHash() const std::string CTxOut::ToString() const { - return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30)); + return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0, 30)); } CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {} diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 6cfd93a9a1..2a457cdae7 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -141,10 +141,13 @@ 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 txout is 34 bytes big, and will + // A typical spendable txout is 34 bytes big, and will // need a CTxIn of at least 148 bytes to spend: - // so dust is a txout less than 546 satoshis + // so dust is a spendable txout less than 546 satoshis // with default minRelayTxFee. + if (scriptPubKey.IsUnspendable()) + return 0; + size_t nSize = GetSerializeSize(SER_DISK,0)+148u; return 3*minRelayTxFee.GetFee(nSize); } diff --git a/src/protocol.h b/src/protocol.h index b5e65032a2..50aeaf44ba 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -75,6 +75,10 @@ enum { // Bitcoin Core does not support this but a patch set called Bitcoin XT does. // See BIP 64 for details on how this is implemented. NODE_GETUTXO = (1 << 1), + // NODE_BLOOM means the node is capable and willing to handle bloom-filtered connections. + // 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), // 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/pubkey.cpp b/src/pubkey.cpp index a4c046bff5..bdab137600 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -54,13 +54,13 @@ bool CPubKey::Decompress() { return true; } -bool CPubKey::Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const { +bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const { assert(IsValid()); assert((nChild >> 31) == 0); assert(begin() + 33 == end()); unsigned char out[64]; BIP32Hash(cc, nChild, *begin(), begin()+1, out); - memcpy(ccChild, out+32, 32); + memcpy(ccChild.begin(), out+32, 32); CECKey key; bool ret = key.SetPubKey(begin(), size()); ret &= key.TweakPublic(out); @@ -75,7 +75,7 @@ void CExtPubKey::Encode(unsigned char code[74]) const { memcpy(code+1, vchFingerprint, 4); code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF; code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF; - memcpy(code+9, vchChainCode, 32); + memcpy(code+9, chaincode.begin(), 32); assert(pubkey.size() == 33); memcpy(code+41, pubkey.begin(), 33); } @@ -84,7 +84,7 @@ void CExtPubKey::Decode(const unsigned char code[74]) { nDepth = code[0]; memcpy(vchFingerprint, code+1, 4); nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8]; - memcpy(vchChainCode, code+9, 32); + memcpy(chaincode.begin(), code+9, 32); pubkey.Set(code+41, code+74); } @@ -93,5 +93,5 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const { CKeyID id = pubkey.GetID(); memcpy(&out.vchFingerprint[0], &id, 4); out.nChild = nChild; - return pubkey.Derive(out.pubkey, out.vchChainCode, nChild, vchChainCode); + return pubkey.Derive(out.pubkey, out.chaincode, nChild, chaincode); } diff --git a/src/pubkey.h b/src/pubkey.h index b0768d4f47..cce9c826e5 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -31,6 +31,8 @@ public: CKeyID(const uint160& in) : uint160(in) {} }; +typedef uint256 ChainCode; + /** An encapsulated public key. */ class CPubKey { @@ -182,20 +184,20 @@ public: bool Decompress(); //! Derive BIP32 child pubkey. - bool Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const; + bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const; }; struct CExtPubKey { unsigned char nDepth; unsigned char vchFingerprint[4]; unsigned int nChild; - unsigned char vchChainCode[32]; + ChainCode chaincode; CPubKey pubkey; - friend bool operator==(const CExtPubKey& a, const CExtPubKey& b) + friend bool operator==(const CExtPubKey &a, const CExtPubKey &b) { return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild && - memcmp(&a.vchChainCode[0], &b.vchChainCode[0], 32) == 0 && a.pubkey == b.pubkey; + a.chaincode == b.chaincode && a.pubkey == b.pubkey; } void Encode(unsigned char code[74]) const; diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 5485d89f3e..8bd1586446 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -14,14 +14,14 @@ #include "csvmodelwriter.h" #include "editaddressdialog.h" #include "guiutil.h" -#include "scicon.h" +#include "platformstyle.h" #include <QIcon> #include <QMenu> #include <QMessageBox> #include <QSortFilterProxyModel> -AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : +AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode mode, Tabs tab, QWidget *parent) : QDialog(parent), ui(new Ui::AddressBookPage), model(0), @@ -30,17 +30,17 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : { ui->setupUi(this); -#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac - ui->newAddress->setIcon(QIcon()); - ui->copyAddress->setIcon(QIcon()); - ui->deleteAddress->setIcon(QIcon()); - ui->exportButton->setIcon(QIcon()); -#else - ui->newAddress->setIcon(SingleColorIcon(":/icons/add")); - ui->copyAddress->setIcon(SingleColorIcon(":/icons/editcopy")); - ui->deleteAddress->setIcon(SingleColorIcon(":/icons/remove")); - ui->exportButton->setIcon(SingleColorIcon(":/icons/export")); -#endif + if (!platformStyle->getImagesOnButtons()) { + ui->newAddress->setIcon(QIcon()); + ui->copyAddress->setIcon(QIcon()); + ui->deleteAddress->setIcon(QIcon()); + ui->exportButton->setIcon(QIcon()); + } else { + ui->newAddress->setIcon(platformStyle->SingleColorIcon(":/icons/add")); + ui->copyAddress->setIcon(platformStyle->SingleColorIcon(":/icons/editcopy")); + ui->deleteAddress->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + ui->exportButton->setIcon(platformStyle->SingleColorIcon(":/icons/export")); + } switch(mode) { @@ -254,8 +254,7 @@ void AddressBookPage::done(int retval) // Figure out which address was selected, and return it QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); - foreach (QModelIndex index, indexes) - { + Q_FOREACH (const QModelIndex& index, indexes) { QVariant address = table->model()->data(index); returnValue = address.toString(); } diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index 5105f09ced..92e6cab9ac 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -9,6 +9,7 @@ class AddressTableModel; class OptionsModel; +class PlatformStyle; namespace Ui { class AddressBookPage; @@ -39,13 +40,13 @@ public: ForEditing /**< Open address book for editing */ }; - explicit AddressBookPage(Mode mode, Tabs tab, QWidget *parent); + explicit AddressBookPage(const PlatformStyle *platformStyle, Mode mode, Tabs tab, QWidget *parent); ~AddressBookPage(); void setModel(AddressTableModel *model); const QString &getReturnValue() const { return returnValue; } -public slots: +public Q_SLOTS: void done(int retval); private: @@ -59,7 +60,7 @@ private: QAction *deleteAction; // to be able to explicitly disable it QString newAddressToSelect; -private slots: +private Q_SLOTS: /** Delete currently selected address entry */ void on_deleteAddress_clicked(); /** Create a new address for receiving coins and / or add a new address book entry */ @@ -80,7 +81,7 @@ private slots: /** New entry/entries were added to address table */ void selectNewAddress(const QModelIndex &parent, int begin, int /*end*/); -signals: +Q_SIGNALS: void sendCoins(QString addr); }; diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 8e20836c65..c5ac07cfc2 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -450,5 +450,5 @@ int AddressTableModel::lookupAddress(const QString &address) const void AddressTableModel::emitDataChanged(int idx) { - emit dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex())); + Q_EMIT dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex())); } diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index 6b34b2eac2..2b7475c4e2 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -84,7 +84,7 @@ private: /** Notify listeners that data changed. */ void emitDataChanged(int index); -public slots: +public Q_SLOTS: /* Update address list from core. */ void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status); diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 229139e65c..441814ff07 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -62,7 +62,7 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : break; case ChangePass: // Ask old passphrase + new passphrase x2 setWindowTitle(tr("Change passphrase")); - ui->warningLabel->setText(tr("Enter the old and new passphrase to the wallet.")); + ui->warningLabel->setText(tr("Enter the old passphrase and new passphrase to the wallet.")); break; } textChanged(); diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index 74d54d18f7..d4d832825a 100644 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -40,7 +40,7 @@ private: WalletModel *model; bool fCapsLock; -private slots: +private Q_SLOTS: void textChanged(); protected: diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp new file mode 100644 index 0000000000..33792af5ba --- /dev/null +++ b/src/qt/bantablemodel.cpp @@ -0,0 +1,181 @@ +// 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 "bantablemodel.h" + +#include "clientmodel.h" +#include "guiconstants.h" +#include "guiutil.h" + +#include "sync.h" +#include "utiltime.h" + +#include <QDebug> +#include <QList> + +bool BannedNodeLessThan::operator()(const CCombinedBan& left, const CCombinedBan& right) const +{ + const CCombinedBan* pLeft = &left; + const CCombinedBan* pRight = &right; + + if (order == Qt::DescendingOrder) + std::swap(pLeft, pRight); + + switch(column) + { + case BanTableModel::Address: + return pLeft->subnet.ToString().compare(pRight->subnet.ToString()) < 0; + case BanTableModel::Bantime: + return pLeft->banEntry.nBanUntil < pRight->banEntry.nBanUntil; + } + + return false; +} + +// private implementation +class BanTablePriv +{ +public: + /** Local cache of peer information */ + QList<CCombinedBan> cachedBanlist; + /** Column to sort nodes by */ + int sortColumn; + /** Order (ascending or descending) to sort nodes by */ + Qt::SortOrder sortOrder; + + /** Pull a full list of banned nodes from CNode into our cache */ + void refreshBanlist() + { + banmap_t banMap; + CNode::GetBanned(banMap); + + cachedBanlist.clear(); +#if QT_VERSION >= 0x040700 + cachedBanlist.reserve(banMap.size()); +#endif + for (banmap_t::iterator it = banMap.begin(); it != banMap.end(); it++) + { + CCombinedBan banEntry; + banEntry.subnet = (*it).first; + banEntry.banEntry = (*it).second; + cachedBanlist.append(banEntry); + } + + if (sortColumn >= 0) + // sort cachedBanlist (use stable sort to prevent rows jumping around unneceesarily) + qStableSort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder)); + } + + int size() const + { + return cachedBanlist.size(); + } + + CCombinedBan *index(int idx) + { + if (idx >= 0 && idx < cachedBanlist.size()) + return &cachedBanlist[idx]; + + return 0; + } +}; + +BanTableModel::BanTableModel(ClientModel *parent) : + QAbstractTableModel(parent), + clientModel(parent) +{ + columns << tr("IP/Netmask") << tr("Banned Until"); + priv = new BanTablePriv(); + // default to unsorted + priv->sortColumn = -1; + + // load initial data + refresh(); +} + +int BanTableModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return priv->size(); +} + +int BanTableModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return columns.length();; +} + +QVariant BanTableModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + CCombinedBan *rec = static_cast<CCombinedBan*>(index.internalPointer()); + + if (role == Qt::DisplayRole) { + switch(index.column()) + { + case Address: + return QString::fromStdString(rec->subnet.ToString()); + case Bantime: + QDateTime date = QDateTime::fromMSecsSinceEpoch(0); + date = date.addSecs(rec->banEntry.nBanUntil); + return date.toString(Qt::SystemLocaleLongDate); + } + } + + return QVariant(); +} + +QVariant BanTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal) + { + if(role == Qt::DisplayRole && section < columns.size()) + { + return columns[section]; + } + } + return QVariant(); +} + +Qt::ItemFlags BanTableModel::flags(const QModelIndex &index) const +{ + if(!index.isValid()) + return 0; + + Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; + return retval; +} + +QModelIndex BanTableModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_UNUSED(parent); + CCombinedBan *data = priv->index(row); + + if (data) + return createIndex(row, column, data); + return QModelIndex(); +} + +void BanTableModel::refresh() +{ + Q_EMIT layoutAboutToBeChanged(); + priv->refreshBanlist(); + Q_EMIT layoutChanged(); +} + +void BanTableModel::sort(int column, Qt::SortOrder order) +{ + priv->sortColumn = column; + priv->sortOrder = order; + refresh(); +} + +bool BanTableModel::shouldShow() +{ + if (priv->size() > 0) + return true; + return false; +}
\ No newline at end of file diff --git a/src/qt/bantablemodel.h b/src/qt/bantablemodel.h new file mode 100644 index 0000000000..c21dd04e31 --- /dev/null +++ b/src/qt/bantablemodel.h @@ -0,0 +1,72 @@ +// Copyright (c) 2011-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. + +#ifndef BITCOIN_QT_BANTABLEMODEL_H +#define BITCOIN_QT_BANTABLEMODEL_H + +#include "net.h" + +#include <QAbstractTableModel> +#include <QStringList> + +class ClientModel; +class BanTablePriv; + +struct CCombinedBan { + CSubNet subnet; + CBanEntry banEntry; +}; + +class BannedNodeLessThan +{ +public: + BannedNodeLessThan(int nColumn, Qt::SortOrder fOrder) : + column(nColumn), order(fOrder) {} + bool operator()(const CCombinedBan& left, const CCombinedBan& right) const; + +private: + int column; + Qt::SortOrder order; +}; + +/** + Qt model providing information about connected peers, similar to the + "getpeerinfo" RPC call. Used by the rpc console UI. + */ +class BanTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit BanTableModel(ClientModel *parent = 0); + void startAutoRefresh(); + void stopAutoRefresh(); + + enum ColumnIndex { + Address = 0, + Bantime = 1 + }; + + /** @name Methods overridden from QAbstractTableModel + @{*/ + int rowCount(const QModelIndex &parent) const; + int columnCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QModelIndex index(int row, int column, const QModelIndex &parent) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + void sort(int column, Qt::SortOrder order); + bool shouldShow(); + /*@}*/ + +public Q_SLOTS: + void refresh(); + +private: + ClientModel *clientModel; + QStringList columns; + BanTablePriv *priv; +}; + +#endif // BITCOIN_QT_BANTABLEMODEL_H diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 018169cfdc..ea7f86d18e 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -8,12 +8,14 @@ #include "bitcoingui.h" +#include "chainparams.h" #include "clientmodel.h" #include "guiconstants.h" #include "guiutil.h" #include "intro.h" #include "networkstyle.h" #include "optionsmodel.h" +#include "platformstyle.h" #include "splashscreen.h" #include "utilitydialog.h" #include "winshutdownmonitor.h" @@ -24,8 +26,8 @@ #endif #include "init.h" -#include "main.h" #include "rpcserver.h" +#include "scheduler.h" #include "ui_interface.h" #include "util.h" @@ -47,6 +49,7 @@ #include <QThread> #include <QTimer> #include <QTranslator> +#include <QSslConfiguration> #if defined(QT_STATICPLUGIN) #include <QtPlugin> @@ -57,7 +60,9 @@ Q_IMPORT_PLUGIN(qtwcodecs) Q_IMPORT_PLUGIN(qkrcodecs) Q_IMPORT_PLUGIN(qtaccessiblewidgets) #else +#if QT_VERSION < 0x050400 Q_IMPORT_PLUGIN(AccessibleFactory) +#endif #if defined(QT_QPA_PLATFORM_XCB) Q_IMPORT_PLUGIN(QXcbIntegrationPlugin); #elif defined(QT_QPA_PLATFORM_WINDOWS) @@ -167,17 +172,18 @@ class BitcoinCore: public QObject public: explicit BitcoinCore(); -public slots: +public Q_SLOTS: void initialize(); void shutdown(); -signals: +Q_SIGNALS: void initializeResult(int retval); void shutdownResult(int retval); void runawayException(const QString &message); private: boost::thread_group threadGroup; + CScheduler scheduler; /// Pass fatal exception message to UI thread void handleRunawayException(const std::exception *e); @@ -213,13 +219,13 @@ public: /// Get window identifier of QMainWindow (BitcoinGUI) WId getMainWinId() const; -public slots: +public Q_SLOTS: void initializeResult(int retval); void shutdownResult(int retval); /// Handle runaway exceptions. Shows a message box with the problem and quits the program. void handleRunawayException(const QString &message); -signals: +Q_SIGNALS: void requestedInitialize(); void requestedShutdown(); void stopThread(); @@ -236,6 +242,7 @@ private: WalletModel *walletModel; #endif int returnValue; + const PlatformStyle *platformStyle; void startThread(); }; @@ -250,7 +257,7 @@ BitcoinCore::BitcoinCore(): void BitcoinCore::handleRunawayException(const std::exception *e) { PrintExceptionContinue(e, "Runaway exception"); - emit runawayException(QString::fromStdString(strMiscWarning)); + Q_EMIT runawayException(QString::fromStdString(strMiscWarning)); } void BitcoinCore::initialize() @@ -258,15 +265,8 @@ void BitcoinCore::initialize() try { qDebug() << __func__ << ": Running AppInit2 in thread"; - int rv = AppInit2(threadGroup); - if(rv) - { - /* Start a dummy RPC thread if no RPC thread is active yet - * to handle timeouts. - */ - StartDummyRPCThread(); - } - emit initializeResult(rv); + int rv = AppInit2(threadGroup, scheduler); + Q_EMIT initializeResult(rv); } catch (const std::exception& e) { handleRunawayException(&e); } catch (...) { @@ -279,11 +279,11 @@ void BitcoinCore::shutdown() try { qDebug() << __func__ << ": Running Shutdown in thread"; - threadGroup.interrupt_all(); + Interrupt(threadGroup); threadGroup.join_all(); Shutdown(); qDebug() << __func__ << ": Shutdown finished"; - emit shutdownResult(1); + Q_EMIT shutdownResult(1); } catch (const std::exception& e) { handleRunawayException(&e); } catch (...) { @@ -305,6 +305,22 @@ BitcoinApplication::BitcoinApplication(int &argc, char **argv): returnValue(0) { setQuitOnLastWindowClosed(false); + + // UI per-platform customization + // This must be done inside the BitcoinApplication constructor, or after it, because + // PlatformStyle::instantiate requires a QApplication +#if defined(Q_OS_MAC) + std::string platformName = "macosx"; +#elif defined(Q_OS_WIN) + std::string platformName = "windows"; +#else + std::string platformName = "other"; +#endif + platformName = GetArg("-uiplatform", platformName); + platformStyle = PlatformStyle::instantiate(QString::fromStdString(platformName)); + if (!platformStyle) // Fall back to "other" if specified name not found + platformStyle = PlatformStyle::instantiate("other"); + assert(platformStyle); } BitcoinApplication::~BitcoinApplication() @@ -312,7 +328,7 @@ BitcoinApplication::~BitcoinApplication() if(coreThread) { qDebug() << __func__ << ": Stopping thread"; - emit stopThread(); + Q_EMIT stopThread(); coreThread->wait(); qDebug() << __func__ << ": Stopped thread"; } @@ -325,6 +341,8 @@ BitcoinApplication::~BitcoinApplication() #endif delete optionsModel; optionsModel = 0; + delete platformStyle; + platformStyle = 0; } #ifdef ENABLE_WALLET @@ -341,7 +359,7 @@ void BitcoinApplication::createOptionsModel() void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) { - window = new BitcoinGUI(networkStyle, 0); + window = new BitcoinGUI(platformStyle, networkStyle, 0); pollShutdownTimer = new QTimer(window); connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown())); @@ -383,7 +401,7 @@ void BitcoinApplication::requestInitialize() { qDebug() << __func__ << ": Requesting initialize"; startThread(); - emit requestedInitialize(); + Q_EMIT requestedInitialize(); } void BitcoinApplication::requestShutdown() @@ -406,7 +424,7 @@ void BitcoinApplication::requestShutdown() ShutdownWindow::showShutdownWindow(window); // Request shutdown from core thread - emit requestedShutdown(); + Q_EMIT requestedShutdown(); } void BitcoinApplication::initializeResult(int retval) @@ -416,6 +434,8 @@ void BitcoinApplication::initializeResult(int retval) returnValue = retval ? 0 : 1; if(retval) { + // Log this only after AppInit2 finishes, as then logging setup is guaranteed complete + qWarning() << "Platform customization:" << platformStyle->getName(); #ifdef ENABLE_WALLET PaymentServer::LoadRootCAs(); paymentServer->setOptionsModel(optionsModel); @@ -427,7 +447,7 @@ void BitcoinApplication::initializeResult(int retval) #ifdef ENABLE_WALLET if(pwalletMain) { - walletModel = new WalletModel(pwalletMain, optionsModel); + walletModel = new WalletModel(platformStyle, pwalletMain, optionsModel); window->addWallet(BitcoinGUI::DEFAULT_WALLET, walletModel); window->setCurrentWallet(BitcoinGUI::DEFAULT_WALLET); @@ -446,7 +466,7 @@ void BitcoinApplication::initializeResult(int retval) { window->show(); } - emit splashFinished(window); + Q_EMIT splashFinished(window); #ifdef ENABLE_WALLET // Now that initialization/startup is done, process any command-line @@ -513,6 +533,13 @@ int main(int argc, char *argv[]) #ifdef Q_OS_MAC QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); #endif +#if QT_VERSION >= 0x050500 + // Because of the POODLE attack it is recommended to disable SSLv3 (https://disablessl3.com/), + // so set SSL protocols to TLS1.0+. + QSslConfiguration sslconf = QSslConfiguration::defaultConfiguration(); + sslconf.setProtocol(QSsl::TlsV1_0OrLater); + QSslConfiguration::setDefaultConfiguration(sslconf); +#endif // Register meta types used for QMetaObject::invokeMethod qRegisterMetaType< bool* >(); diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index 63af146fd0..c899e95506 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -45,6 +45,7 @@ <file alias="about">res/icons/about.png</file> <file alias="about_qt">res/icons/about_qt.png</file> <file alias="verify">res/icons/verify.png</file> + <file alias="warning">res/icons/warning.png</file> </qresource> <qresource prefix="/movies"> <file alias="spinner-000">res/movies/spinner-000.png</file> diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index d31a1e018b..d19b9fd4af 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -61,7 +61,7 @@ public: void setValue(const CAmount& value) { lineEdit()->setText(BitcoinUnits::format(currentUnit, value, false, BitcoinUnits::separatorAlways)); - emit valueChanged(); + Q_EMIT valueChanged(); } void stepBy(int steps) @@ -184,7 +184,7 @@ protected: return rv; } -signals: +Q_SIGNALS: void valueChanged(); }; diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h index b047e6c51a..3703b1f8d7 100644 --- a/src/qt/bitcoinamountfield.h +++ b/src/qt/bitcoinamountfield.h @@ -56,7 +56,7 @@ public: */ QWidget *setupTabChain(QWidget *prev); -signals: +Q_SIGNALS: void valueChanged(); protected: @@ -67,7 +67,7 @@ private: AmountSpinBox *amount; QValueComboBox *unit; -private slots: +private Q_SLOTS: void unitChanged(int idx); }; diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 670d54c7e3..d930d15953 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -13,8 +13,8 @@ #include "openuridialog.h" #include "optionsdialog.h" #include "optionsmodel.h" +#include "platformstyle.h" #include "rpcconsole.h" -#include "scicon.h" #include "utilitydialog.h" #ifdef ENABLE_WALLET @@ -60,7 +60,7 @@ const QString BitcoinGUI::DEFAULT_WALLET = "~Default"; -BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : +BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent) : QMainWindow(parent), clientModel(0), walletFrame(0), @@ -97,8 +97,10 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : trayIconMenu(0), notificator(0), rpcConsole(0), + helpMessageDialog(0), prevBlocks(0), - spinnerFrame(0) + spinnerFrame(0), + platformStyle(platformStyle) { GUIUtil::restoreWindowGeometry("nWindow", QSize(850, 550), this); @@ -130,12 +132,13 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : setUnifiedTitleAndToolBarOnMac(true); #endif - rpcConsole = new RPCConsole(0); + rpcConsole = new RPCConsole(platformStyle, 0); + helpMessageDialog = new HelpMessageDialog(this, false); #ifdef ENABLE_WALLET if(enableWallet) { /** Create wallet frame and make it the central widget */ - walletFrame = new WalletFrame(this); + walletFrame = new WalletFrame(platformStyle, this); setCentralWidget(walletFrame); } else #endif // ENABLE_WALLET @@ -175,7 +178,7 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks); frameBlocksLayout->setContentsMargins(3,0,3,0); frameBlocksLayout->setSpacing(3); - unitDisplayControl = new UnitDisplayStatusBarControl(); + unitDisplayControl = new UnitDisplayStatusBarControl(platformStyle); labelEncryptionIcon = new QLabel(); labelConnectionsIcon = new QLabel(); labelBlocksIcon = new QLabel(); @@ -212,11 +215,6 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : statusBar()->addWidget(progressBar); statusBar()->addPermanentWidget(frameBlocks); - connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show())); - - // prevents an open debug window from becoming stuck/unusable on client shutdown - connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide())); - // Install event filter to be able to catch status tip events (QEvent::StatusTip) this->installEventFilter(this); @@ -247,36 +245,36 @@ void BitcoinGUI::createActions() { QActionGroup *tabGroup = new QActionGroup(this); - overviewAction = new QAction(SingleColorIcon(":/icons/overview"), tr("&Overview"), this); + overviewAction = new QAction(platformStyle->SingleColorIcon(":/icons/overview"), tr("&Overview"), this); overviewAction->setStatusTip(tr("Show general overview of wallet")); overviewAction->setToolTip(overviewAction->statusTip()); overviewAction->setCheckable(true); overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1)); tabGroup->addAction(overviewAction); - sendCoinsAction = new QAction(SingleColorIcon(":/icons/send"), tr("&Send"), this); + sendCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/send"), tr("&Send"), this); sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address")); sendCoinsAction->setToolTip(sendCoinsAction->statusTip()); sendCoinsAction->setCheckable(true); sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2)); tabGroup->addAction(sendCoinsAction); - sendCoinsMenuAction = new QAction(TextColorIcon(":/icons/send"), sendCoinsAction->text(), this); + sendCoinsMenuAction = new QAction(platformStyle->TextColorIcon(":/icons/send"), sendCoinsAction->text(), this); sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip()); sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip()); - receiveCoinsAction = new QAction(SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this); + receiveCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this); receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)")); receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip()); receiveCoinsAction->setCheckable(true); receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3)); tabGroup->addAction(receiveCoinsAction); - receiveCoinsMenuAction = new QAction(TextColorIcon(":/icons/receiving_addresses"), receiveCoinsAction->text(), this); + receiveCoinsMenuAction = new QAction(platformStyle->TextColorIcon(":/icons/receiving_addresses"), receiveCoinsAction->text(), this); receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip()); receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip()); - historyAction = new QAction(SingleColorIcon(":/icons/history"), tr("&Transactions"), this); + historyAction = new QAction(platformStyle->SingleColorIcon(":/icons/history"), tr("&Transactions"), this); historyAction->setStatusTip(tr("Browse transaction history")); historyAction->setToolTip(historyAction->statusTip()); historyAction->setCheckable(true); @@ -300,46 +298,46 @@ void BitcoinGUI::createActions() connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage())); #endif // ENABLE_WALLET - quitAction = new QAction(TextColorIcon(":/icons/quit"), tr("E&xit"), this); + quitAction = new QAction(platformStyle->TextColorIcon(":/icons/quit"), tr("E&xit"), this); quitAction->setStatusTip(tr("Quit application")); quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); quitAction->setMenuRole(QAction::QuitRole); - aboutAction = new QAction(TextColorIcon(":/icons/about"), tr("&About Bitcoin Core"), this); + aboutAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&About Bitcoin Core"), this); aboutAction->setStatusTip(tr("Show information about Bitcoin Core")); aboutAction->setMenuRole(QAction::AboutRole); - aboutQtAction = new QAction(TextColorIcon(":/icons/about_qt"), tr("About &Qt"), this); + 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(TextColorIcon(":/icons/options"), tr("&Options..."), this); + optionsAction = new QAction(platformStyle->TextColorIcon(":/icons/options"), tr("&Options..."), this); optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin Core")); optionsAction->setMenuRole(QAction::PreferencesRole); - toggleHideAction = new QAction(TextColorIcon(":/icons/about"), tr("&Show / Hide"), this); + toggleHideAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&Show / Hide"), this); toggleHideAction->setStatusTip(tr("Show or hide the main Window")); - encryptWalletAction = new QAction(TextColorIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this); + encryptWalletAction = new QAction(platformStyle->TextColorIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this); encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet")); encryptWalletAction->setCheckable(true); - backupWalletAction = new QAction(TextColorIcon(":/icons/filesave"), tr("&Backup Wallet..."), this); + backupWalletAction = new QAction(platformStyle->TextColorIcon(":/icons/filesave"), tr("&Backup Wallet..."), this); backupWalletAction->setStatusTip(tr("Backup wallet to another location")); - changePassphraseAction = new QAction(TextColorIcon(":/icons/key"), tr("&Change Passphrase..."), this); + changePassphraseAction = new QAction(platformStyle->TextColorIcon(":/icons/key"), tr("&Change Passphrase..."), this); changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption")); - signMessageAction = new QAction(TextColorIcon(":/icons/edit"), tr("Sign &message..."), this); + signMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/edit"), tr("Sign &message..."), this); signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them")); - verifyMessageAction = new QAction(TextColorIcon(":/icons/verify"), tr("&Verify message..."), this); + verifyMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/verify"), tr("&Verify message..."), this); verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses")); - openRPCConsoleAction = new QAction(TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this); + openRPCConsoleAction = new QAction(platformStyle->TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this); openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console")); - usedSendingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Sending addresses..."), this); + usedSendingAddressesAction = new QAction(platformStyle->TextColorIcon(":/icons/address-book"), tr("&Sending addresses..."), this); usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels")); - usedReceivingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Receiving addresses..."), this); + usedReceivingAddressesAction = new QAction(platformStyle->TextColorIcon(":/icons/address-book"), tr("&Receiving addresses..."), this); usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels")); - openAction = new QAction(TextColorIcon(":/icons/open"), tr("Open &URI..."), this); + openAction = new QAction(platformStyle->TextColorIcon(":/icons/open"), tr("Open &URI..."), this); openAction->setStatusTip(tr("Open a bitcoin: URI or payment request")); - showHelpMessageAction = new QAction(TextColorIcon(":/icons/info"), tr("&Command-line options"), this); + 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")); @@ -349,6 +347,10 @@ void BitcoinGUI::createActions() connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked())); connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden())); connect(showHelpMessageAction, SIGNAL(triggered()), this, SLOT(showHelpMessageClicked())); + connect(openRPCConsoleAction, SIGNAL(triggered()), this, SLOT(showDebugWindow())); + // prevents an open debug window from becoming stuck/unusable on client shutdown + connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide())); + #ifdef ENABLE_WALLET if(walletFrame) { @@ -414,6 +416,7 @@ void BitcoinGUI::createToolBars() if(walletFrame) { QToolBar *toolbar = addToolBar(tr("Tabs toolbar")); + toolbar->setMovable(false); toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); toolbar->addAction(overviewAction); toolbar->addAction(sendCoinsAction); @@ -586,11 +589,17 @@ void BitcoinGUI::aboutClicked() dlg.exec(); } +void BitcoinGUI::showDebugWindow() +{ + rpcConsole->showNormal(); + rpcConsole->show(); + rpcConsole->raise(); + rpcConsole->activateWindow(); +} + void BitcoinGUI::showHelpMessageClicked() { - HelpMessageDialog *help = new HelpMessageDialog(this, false); - help->setAttribute(Qt::WA_DeleteOnClose); - help->show(); + helpMessageDialog->show(); } #ifdef ENABLE_WALLET @@ -599,7 +608,7 @@ void BitcoinGUI::openClicked() OpenURIDialog dlg(this); if(dlg.exec()) { - emit receivedURI(dlg.getURI()); + Q_EMIT receivedURI(dlg.getURI()); } } @@ -649,7 +658,7 @@ void BitcoinGUI::setNumConnections(int count) case 7: case 8: case 9: icon = ":/icons/connect_3"; break; default: icon = ":/icons/connect_4"; break; } - labelConnectionsIcon->setPixmap(SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelConnectionsIcon->setPixmap(platformStyle->SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count)); } @@ -684,13 +693,13 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate) QDateTime currentDate = QDateTime::currentDateTime(); qint64 secs = blockDate.secsTo(currentDate); - tooltip = tr("Processed %n blocks of transaction history.", "", count); + tooltip = tr("Processed %n block(s) of transaction history.", "", count); // Set icon state: spinning if catching up, tick otherwise if(secs < 90*60) { tooltip = tr("Up to date") + QString(".<br>") + tooltip; - labelBlocksIcon->setPixmap(SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); + labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); #ifdef ENABLE_WALLET if(walletFrame) @@ -736,7 +745,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate) tooltip = tr("Catching up...") + QString("<br>") + tooltip; if(count != prevBlocks) { - labelBlocksIcon->setPixmap(SingleColorIcon(QString( + labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(QString( ":/movies/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0'))) .pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES; @@ -885,9 +894,9 @@ void BitcoinGUI::dropEvent(QDropEvent *event) { if(event->mimeData()->hasUrls()) { - foreach(const QUrl &uri, event->mimeData()->urls()) + Q_FOREACH(const QUrl &uri, event->mimeData()->urls()) { - emit receivedURI(uri.toString()); + Q_EMIT receivedURI(uri.toString()); } } event->acceptProposedAction(); @@ -930,7 +939,7 @@ void BitcoinGUI::setEncryptionStatus(int status) break; case WalletModel::Unlocked: labelEncryptionIcon->show(); - labelEncryptionIcon->setPixmap(SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>")); encryptWalletAction->setChecked(true); changePassphraseAction->setEnabled(true); @@ -938,7 +947,7 @@ void BitcoinGUI::setEncryptionStatus(int status) break; case WalletModel::Locked: labelEncryptionIcon->show(); - labelEncryptionIcon->setPixmap(SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>")); encryptWalletAction->setChecked(true); changePassphraseAction->setEnabled(true); @@ -1040,7 +1049,7 @@ void BitcoinGUI::unsubscribeFromCoreSignals() uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3)); } -UnitDisplayStatusBarControl::UnitDisplayStatusBarControl() : +UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *platformStyle) : optionsModel(0), menu(0) { @@ -1049,13 +1058,13 @@ UnitDisplayStatusBarControl::UnitDisplayStatusBarControl() : QList<BitcoinUnits::Unit> units = BitcoinUnits::availableUnits(); int max_width = 0; const QFontMetrics fm(font()); - foreach (const BitcoinUnits::Unit unit, units) + Q_FOREACH (const BitcoinUnits::Unit unit, units) { max_width = qMax(max_width, fm.width(BitcoinUnits::name(unit))); } setMinimumSize(max_width, 0); setAlignment(Qt::AlignRight | Qt::AlignVCenter); - setStyleSheet(QString("QLabel { color : %1 }").arg(SingleColor().name())); + setStyleSheet(QString("QLabel { color : %1 }").arg(platformStyle->SingleColor().name())); } /** So that it responds to button clicks */ @@ -1068,7 +1077,7 @@ void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event) void UnitDisplayStatusBarControl::createContextMenu() { menu = new QMenu(); - foreach(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) + Q_FOREACH(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) { QAction *menuAction = new QAction(QString(BitcoinUnits::name(u)), this); menuAction->setData(QVariant(u)); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 494541f002..717f2bd12d 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -22,11 +22,13 @@ class ClientModel; class NetworkStyle; class Notificator; class OptionsModel; +class PlatformStyle; class RPCConsole; class SendCoinsRecipient; class UnitDisplayStatusBarControl; class WalletFrame; class WalletModel; +class HelpMessageDialog; class CWallet; @@ -47,7 +49,7 @@ class BitcoinGUI : public QMainWindow public: static const QString DEFAULT_WALLET; - explicit BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent = 0); + explicit BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent = 0); ~BitcoinGUI(); /** Set the client model. @@ -112,11 +114,14 @@ private: QMenu *trayIconMenu; Notificator *notificator; RPCConsole *rpcConsole; + HelpMessageDialog *helpMessageDialog; /** Keep track of previous number of blocks, to detect progress */ int prevBlocks; int spinnerFrame; + const PlatformStyle *platformStyle; + /** Create the main UI actions. */ void createActions(); /** Create the menu bar and sub-menus. */ @@ -136,11 +141,11 @@ private: /** Disconnect core signals from GUI client */ void unsubscribeFromCoreSignals(); -signals: +Q_SIGNALS: /** Signal raised when a URI was entered or dragged to the GUI */ void receivedURI(const QString &uri); -public slots: +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 */ @@ -168,7 +173,7 @@ public slots: void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label); #endif // ENABLE_WALLET -private slots: +private Q_SLOTS: #ifdef ENABLE_WALLET /** Switch to overview (home) page */ void gotoOverviewPage(); @@ -191,6 +196,8 @@ private slots: void optionsClicked(); /** Show about dialog */ void aboutClicked(); + /** Show debug window */ + void showDebugWindow(); /** Show help message dialog */ void showHelpMessageClicked(); #ifndef Q_OS_MAC @@ -215,7 +222,7 @@ class UnitDisplayStatusBarControl : public QLabel Q_OBJECT public: - explicit UnitDisplayStatusBarControl(); + explicit UnitDisplayStatusBarControl(const PlatformStyle *platformStyle); /** Lets the control know about the Options Model (and its signals) */ void setOptionsModel(OptionsModel *optionsModel); @@ -232,7 +239,7 @@ private: /** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */ void createContextMenu(); -private slots: +private Q_SLOTS: /** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */ void updateDisplayUnit(int newUnits); /** Tells underlying optionsModel to update its current display unit. */ diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 7f372debad..3cde2657cf 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -17,9 +17,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "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"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"An error occurred while setting up the RPC address %s port %u for listening: " -"%s"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Bind to given address and always listen on it. Use [host]:port notation for " "IPv6"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -33,9 +30,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Cannot obtain a lock on data directory %s. Bitcoin Core is probably already " "running."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Continuously rate-limit free transactions to <n>*1000 bytes per minute " -"(default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Create new files with system default permissions, instead of umask 077 (only " "effective with disabled wallet functionality)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -48,9 +42,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Distributed under the MIT software license, see the accompanying file " "COPYING or <http://www.opensource.org/licenses/mit-license.php>."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Enter regression test mode, which uses a special chain in which blocks can " -"be solved instantly."), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Error: Listening for incoming connections failed (listen returned error %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Error: Unsupported argument -socks found. Setting SOCKS version isn't " @@ -65,42 +56,40 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Execute command when the best block changes (%s in cmd is replaced by block " "hash)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Fees (in BTC/Kb) smaller than this are considered zero fee for relaying " +"Fees (in %s/kB) smaller than this are considered zero fee for relaying " "(default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Fees (in BTC/Kb) smaller than this are considered zero fee for transaction " -"creation (default: %s)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" -"Flush database activity from memory pool to disk log every <n> megabytes " -"(default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "How thorough the block verification of -checkblocks is (0-4, default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"If <category> is not supplied or if <category> = 1, output all debugging " +"information."), +QT_TRANSLATE_NOOP("bitcoin-core", "" "If paytxfee is not set, include enough fee so transactions begin " "confirmation on average within n blocks (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"In this mode -genproclimit controls how many blocks are generated " -"immediately."), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay " "fee of %s to prevent stuck transactions)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Log transaction priority and fee per kB when mining blocks (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Maintain a full transaction index, used by the getrawtransaction rpc call " "(default: %u)"), 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 to use in a single wallet transaction, setting 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)"), 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 <category> is optional)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Prune configured below the minimum of %d MB. Please use a higher number."), +"Please check that your computer's date and time are correct! If your clock " +"is wrong Bitcoin Core 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", "" +"Prune: last wallet synchronisation goes beyond pruned data. You need to -" +"reindex (download the whole blockchain again in case of pruned node)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Query for peer addresses via DNS lookup, if low on addresses (default: 1 " "unless -connect)"), @@ -108,10 +97,13 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Randomize credentials for every proxy connection. This enables Tor stream " "isolation (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Reduce storage requirements by pruning (deleting) old blocks. This mode " -"disables wallet support and is incompatible with -txindex."), +"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)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Require high priority for relaying free or low-fee transactions (default: %u)"), +"Rescans are not possible in pruned mode. You will need to use -reindex which " +"will download the whole blockchain again."), QT_TRANSLATE_NOOP("bitcoin-core", "" "Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -121,6 +113,11 @@ 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", "" +"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"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "The transaction amount is too small to send after the fee has been deducted"), QT_TRANSLATE_NOOP("bitcoin-core", "" "This is a pre-release test build - use at your own risk - do not use for " @@ -130,37 +127,26 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software " "written by Eric Young and UPnP software written by Thomas Bernard."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"To use bitcoind, or the -server option to bitcoin-qt, you must set an " -"rpcpassword in the configuration file:\n" -"%s\n" -"It is recommended you use the following random password:\n" -"rpcuser=bitcoinrpc\n" -"rpcpassword=%s\n" -"(you do not need to remember this password)\n" -"The username and password MUST NOT be the same.\n" -"If the file does not exist, create it with owner-readable-only file " -"permissions.\n" -"It is also recommended to set alertnotify so you are notified of problems;\n" -"for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Unable to bind to %s on this computer. Bitcoin Core is probably already " "running."), 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: " "%s)"), 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: -maxtxfee is set very high! Fees this large could be paid on a " "single transaction."), QT_TRANSLATE_NOOP("bitcoin-core", "" "Warning: -paytxfee is set very high! This is the transaction fee you will " "pay if you send a transaction."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Warning: Please check that your computer's date and time are correct! If " -"your clock is wrong Bitcoin Core will not work properly."), -QT_TRANSLATE_NOOP("bitcoin-core", "" -"Warning: Reverting this setting requires re-downloading the entire " -"blockchain."), -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", "" @@ -184,21 +170,17 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "mode. This will redownload the entire blockchain"), QT_TRANSLATE_NOOP("bitcoin-core", "(default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "(default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "(default: 0 = disable pruning blocks,"), QT_TRANSLATE_NOOP("bitcoin-core", "(default: 1)"), QT_TRANSLATE_NOOP("bitcoin-core", "<category> can be:"), -QT_TRANSLATE_NOOP("bitcoin-core", ">%u = target size in MiB to use for block files)"), 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", "Acceptable ciphers (default: %s)"), +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", "Allow self signed root certificates (default: 0)"), QT_TRANSLATE_NOOP("bitcoin-core", "Always query for peer addresses via DNS lookup (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet.dat"), QT_TRANSLATE_NOOP("bitcoin-core", "Block creation options:"), -QT_TRANSLATE_NOOP("bitcoin-core", "Can't run with a wallet in prune mode."), 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'"), @@ -211,12 +193,14 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, 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", "Corrupted block database detected"), -QT_TRANSLATE_NOOP("bitcoin-core", "Could not parse -rpcbind value %s as network address"), QT_TRANSLATE_NOOP("bitcoin-core", "Debugging/Testing options:"), -QT_TRANSLATE_NOOP("bitcoin-core", "Disable safemode, override a real safe mode event (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Do not load the wallet and disable wallet RPC calls"), QT_TRANSLATE_NOOP("bitcoin-core", "Do you want to rebuild the block database now?"), QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"), +QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish hash block in <address>"), +QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish hash transaction in <address>"), +QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish raw block in <address>"), +QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish raw transaction in <address>"), 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 block database"), @@ -226,15 +210,13 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires new 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"), -QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occured, see debug.log for details"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occurred, see debug.log for details"), QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"), QT_TRANSLATE_NOOP("bitcoin-core", "Error: Unsupported argument -tor found, use -onion."), 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 BTC/kB) to add to transactions you send (default: %s)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Force safe mode (default: %u)"), +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", "If <category> is not supplied, output all debugging information."), QT_TRANSLATE_NOOP("bitcoin-core", "Importing..."), QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000??.dat file"), QT_TRANSLATE_NOOP("bitcoin-core", "Include IP addresses in debug output (default: %u)"), @@ -251,7 +233,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s' ( QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable transactions in memory (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Limit size of signature cache to <n> entries (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: %u or testnet: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."), @@ -264,29 +245,24 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 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."), -QT_TRANSLATE_NOOP("bitcoin-core", "Only accept block chain matching built-in checkpoints (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (ipv4, ipv6 or onion)"), 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", "Prune cannot be configured with a negative value."), QT_TRANSLATE_NOOP("bitcoin-core", "Prune mode is incompatible with -txindex."), -QT_TRANSLATE_NOOP("bitcoin-core", "RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Pruning blockstore..."), QT_TRANSLATE_NOOP("bitcoin-core", "RPC server options:"), -QT_TRANSLATE_NOOP("bitcoin-core", "RPC support for HTTP persistent connections (default: %d)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Randomly drop 1 of every <n> network messages"), -QT_TRANSLATE_NOOP("bitcoin-core", "Randomly fuzz 1 of every <n> network messages"), -QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild block chain index from current blk000??.dat files"), +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", "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)"), QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions"), QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."), -QT_TRANSLATE_NOOP("bitcoin-core", "Run a thread to flush wallet periodically (default: %u)"), 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", "Server certificate file (default: %s)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set SSL root certificates for payment request (default: -system-)"), 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 <n> (default: %u)"), @@ -294,7 +270,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Set language, for example \"de_DE\" (default: 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", "Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Show all debugging options (usage: --help -help-debug)"), QT_TRANSLATE_NOOP("bitcoin-core", "Show splash screen on startup (default: 1)"), QT_TRANSLATE_NOOP("bitcoin-core", "Shrink debug.log file on client startup (default: 1 when no -debug)"), @@ -307,11 +282,9 @@ 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", "Start minimized"), -QT_TRANSLATE_NOOP("bitcoin-core", "Stop running after importing blocks from disk (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", "This is intended for regression testing tools and app development."), QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amount too small"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must be positive"), @@ -319,11 +292,10 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large for fee policy"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large"), QT_TRANSLATE_NOOP("bitcoin-core", "UI Options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %s)"), +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", "Upgrade wallet to latest format"), -QT_TRANSLATE_NOOP("bitcoin-core", "Use OpenSSL (https) for JSON-RPC connections"), QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: 1 when listening)"), QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"), QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"), QT_TRANSLATE_NOOP("bitcoin-core", "Verifying blocks..."), @@ -332,11 +304,12 @@ 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 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: This version is obsolete; upgrade required!"), QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Unsupported argument -benchmark ignored, use -debug=bench."), QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Unsupported argument -debugnet ignored, use -debug=net."), 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", "on startup"), QT_TRANSLATE_NOOP("bitcoin-core", "wallet.dat corrupt, salvage failed"), }; diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index dc32f81571..0900a35cc4 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -4,6 +4,7 @@ #include "clientmodel.h" +#include "bantablemodel.h" #include "guiconstants.h" #include "peertablemodel.h" @@ -11,7 +12,6 @@ #include "chainparams.h" #include "checkpoints.h" #include "clientversion.h" -#include "main.h" #include "net.h" #include "ui_interface.h" #include "util.h" @@ -27,6 +27,7 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : QObject(parent), optionsModel(optionsModel), peerTableModel(0), + banTableModel(0), cachedNumBlocks(0), cachedBlockDate(QDateTime()), cachedReindexing(0), @@ -34,6 +35,7 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : pollTimer(0) { peerTableModel = new PeerTableModel(this); + banTableModel = new BanTableModel(this); pollTimer = new QTimer(this); connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer())); pollTimer->start(MODEL_UPDATE_DELAY); @@ -53,9 +55,9 @@ int ClientModel::getNumConnections(unsigned int flags) const return vNodes.size(); int nNum = 0; - BOOST_FOREACH(CNode* pnode, vNodes) - if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) - nNum++; + BOOST_FOREACH(const CNode* pnode, vNodes) + if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) + nNum++; return nNum; } @@ -89,7 +91,7 @@ QDateTime ClientModel::getLastBlockDate() const double ClientModel::getVerificationProgress() const { LOCK(cs_main); - return Checkpoints::GuessVerificationProgress(chainActive.Tip()); + return Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip()); } void ClientModel::updateTimer() @@ -117,15 +119,15 @@ void ClientModel::updateTimer() cachedReindexing = fReindex; cachedImporting = fImporting; - emit numBlocksChanged(newNumBlocks, newBlockDate); + Q_EMIT numBlocksChanged(newNumBlocks, newBlockDate); } - emit bytesChanged(getTotalBytesRecv(), getTotalBytesSent()); + Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent()); } void ClientModel::updateNumConnections(int numConnections) { - emit numConnectionsChanged(numConnections); + Q_EMIT numConnectionsChanged(numConnections); } void ClientModel::updateAlert(const QString &hash, int status) @@ -138,11 +140,11 @@ void ClientModel::updateAlert(const QString &hash, int status) CAlert alert = CAlert::getAlertByHash(hash_256); if(!alert.IsNull()) { - emit message(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), CClientUIInterface::ICON_ERROR); + Q_EMIT message(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), CClientUIInterface::ICON_ERROR); } } - emit alertsChanged(getStatusBarWarnings()); + Q_EMIT alertsChanged(getStatusBarWarnings()); } bool ClientModel::inInitialBlockDownload() const @@ -177,11 +179,21 @@ PeerTableModel *ClientModel::getPeerTableModel() return peerTableModel; } +BanTableModel *ClientModel::getBanTableModel() +{ + return banTableModel; +} + QString ClientModel::formatFullVersion() const { return QString::fromStdString(FormatFullVersion()); } +QString ClientModel::formatSubVersion() const +{ + return QString::fromStdString(strSubVersion); +} + QString ClientModel::formatBuildDate() const { return QString::fromStdString(CLIENT_DATE); @@ -202,6 +214,11 @@ QString ClientModel::formatClientStartupTime() const return QDateTime::fromTime_t(nClientStartupTime).toString(); } +void ClientModel::updateBanlist() +{ + banTableModel->refresh(); +} + // Handlers for core signals static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress) { @@ -226,12 +243,19 @@ static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, Ch Q_ARG(int, status)); } +static void BannedListChanged(ClientModel *clientmodel) +{ + qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__); + QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection); +} + 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.BannedListChanged.connect(boost::bind(BannedListChanged, this)); } void ClientModel::unsubscribeFromCoreSignals() @@ -240,4 +264,5 @@ void ClientModel::unsubscribeFromCoreSignals() 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.BannedListChanged.disconnect(boost::bind(BannedListChanged, this)); } diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 214701810c..627bdf862d 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -9,6 +9,7 @@ #include <QDateTime> class AddressTableModel; +class BanTableModel; class OptionsModel; class PeerTableModel; class TransactionTableModel; @@ -44,6 +45,7 @@ public: OptionsModel *getOptionsModel(); PeerTableModel *getPeerTableModel(); + BanTableModel *getBanTableModel(); //! Return number of connections, default is in- and outbound (total) int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const; @@ -63,6 +65,7 @@ public: QString getStatusBarWarnings() const; QString formatFullVersion() const; + QString formatSubVersion() const; QString formatBuildDate() const; bool isReleaseVersion() const; QString clientName() const; @@ -71,6 +74,7 @@ public: private: OptionsModel *optionsModel; PeerTableModel *peerTableModel; + BanTableModel *banTableModel; int cachedNumBlocks; QDateTime cachedBlockDate; @@ -82,7 +86,7 @@ private: void subscribeToCoreSignals(); void unsubscribeFromCoreSignals(); -signals: +Q_SIGNALS: void numConnectionsChanged(int count); void numBlocksChanged(int count, const QDateTime& blockDate); void alertsChanged(const QString &warnings); @@ -94,10 +98,11 @@ signals: // Show progress dialog e.g. for verifychain void showProgress(const QString &title, int nProgress); -public slots: +public Q_SLOTS: void updateTimer(); void updateNumConnections(int numConnections); void updateAlert(const QString &hash, int status); + void updateBanlist(); }; #endif // BITCOIN_QT_CLIENTMODEL_H diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 0a60632bfa..51008ad2de 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -9,12 +9,13 @@ #include "bitcoinunits.h" #include "guiutil.h" #include "optionsmodel.h" -#include "scicon.h" +#include "platformstyle.h" +#include "txmempool.h" #include "walletmodel.h" #include "coincontrol.h" #include "init.h" -#include "main.h" +#include "main.h" // For minRelayTxFee #include "wallet/wallet.h" #include <boost/assign/list_of.hpp> // for 'map_list_of()' @@ -30,15 +31,15 @@ #include <QTreeWidget> #include <QTreeWidgetItem> -using namespace std; QList<CAmount> CoinControlDialog::payAmounts; CCoinControl* CoinControlDialog::coinControl = new CCoinControl(); bool CoinControlDialog::fSubtractFeeFromAmount = false; -CoinControlDialog::CoinControlDialog(QWidget *parent) : +CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::CoinControlDialog), - model(0) + model(0), + platformStyle(platformStyle) { ui->setupUi(this); @@ -118,7 +119,7 @@ CoinControlDialog::CoinControlDialog(QWidget *parent) : // (un)select all connect(ui->pushButtonSelectAll, SIGNAL(clicked()), this, SLOT(buttonSelectAllClicked())); - // change coin control first column label due Qt4 bug. + // change coin control first column label due Qt4 bug. // see https://github.com/bitcoin/bitcoin/issues/5716 ui->treeWidget->headerItem()->setText(COLUMN_CHECKBOX, QString()); @@ -129,11 +130,11 @@ CoinControlDialog::CoinControlDialog(QWidget *parent) : 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 dont show it - ui->treeWidget->setColumnHidden(COLUMN_VOUT_INDEX, true); // store vout index in this column, but dont show it - ui->treeWidget->setColumnHidden(COLUMN_AMOUNT_INT64, true); // store amount int64 in this column, but dont show it - ui->treeWidget->setColumnHidden(COLUMN_PRIORITY_INT64, true); // store priority int64 in this column, but dont show it - ui->treeWidget->setColumnHidden(COLUMN_DATE_INT64, true); // store date int64 in this column, but dont show it + ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transacton 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); @@ -280,7 +281,7 @@ void CoinControlDialog::lockCoin() COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); model->lockCoin(outpt); contextMenuItem->setDisabled(true); - contextMenuItem->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed")); + contextMenuItem->setIcon(COLUMN_CHECKBOX, platformStyle->SingleColorIcon(":/icons/lock_closed")); updateLabelLocked(); } @@ -408,8 +409,8 @@ 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 childs are partially selected. But the parent node should be fully selected - // as well as the childs. Childs should never be partially selected in the first place. + // 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. #if QT_VERSION >= 0x050000 else if (column == COLUMN_CHECKBOX && item->childCount() > 0) @@ -442,7 +443,7 @@ QString CoinControlDialog::getPriorityLabel(double dPriority, double mempoolEsti // shows count of locked unspent outputs void CoinControlDialog::updateLabelLocked() { - vector<COutPoint> vOutpts; + std::vector<COutPoint> vOutpts; model->listLockedCoins(vOutpts); if (vOutpts.size() > 0) { @@ -461,13 +462,13 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) CAmount nPayAmount = 0; bool fDust = false; CMutableTransaction txDummy; - foreach(const CAmount &amount, CoinControlDialog::payAmounts) + Q_FOREACH(const CAmount &amount, CoinControlDialog::payAmounts) { nPayAmount += amount; if (amount > 0) { - CTxOut txout(amount, (CScript)vector<unsigned char>(24, 0)); + CTxOut txout(amount, (CScript)std::vector<unsigned char>(24, 0)); txDummy.vout.push_back(txout); if (txout.IsDust(::minRelayTxFee)) fDust = true; @@ -487,13 +488,12 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) int nQuantityUncompressed = 0; bool fAllowFree = false; - vector<COutPoint> vCoinControl; - vector<COutput> vOutputs; + std::vector<COutPoint> vCoinControl; + std::vector<COutput> vOutputs; coinControl->ListSelected(vCoinControl); model->getOutputs(vCoinControl, vOutputs); - BOOST_FOREACH(const COutput& out, vOutputs) - { + BOOST_FOREACH(const COutput& out, vOutputs) { // unselect already spent, very unlikely scenario, this could happen // when selected are spent elsewhere, like rpc or another computer uint256 txhash = out.tx->GetHash(); @@ -569,7 +569,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // Never create dust outputs; if we would, just add the dust to the fee. if (nChange > 0 && nChange < CENT) { - CTxOut txout(nChange, (CScript)vector<unsigned char>(24, 0)); + CTxOut txout(nChange, (CScript)std::vector<unsigned char>(24, 0)); if (txout.IsDust(::minRelayTxFee)) { if (CoinControlDialog::fSubtractFeeFromAmount) // dust-change will be raised until no dust @@ -635,15 +635,15 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) l7->setStyleSheet((fDust) ? "color:red;" : ""); // Dust = "yes" // tool tips - QString toolTip1 = tr("This label turns red, if the transaction size is greater than 1000 bytes.") + "<br /><br />"; + QString toolTip1 = tr("This label turns red if the transaction size is greater than 1000 bytes.") + "<br /><br />"; toolTip1 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CWallet::minTxFee.GetFeePerK())) + "<br /><br />"; toolTip1 += tr("Can vary +/- 1 byte per input."); QString toolTip2 = tr("Transactions with higher priority are more likely to get included into a block.") + "<br /><br />"; - toolTip2 += tr("This label turns red, if the priority is smaller than \"medium\".") + "<br /><br />"; + toolTip2 += tr("This label turns red if the priority is smaller than \"medium\".") + "<br /><br />"; toolTip2 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CWallet::minTxFee.GetFeePerK())); - 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::formatWithUnit(nDisplayUnit, ::minRelayTxFee.GetFee(546))); // how many satoshis the estimated fee can vary per byte we guess wrong double dFeeVary; @@ -688,11 +688,10 @@ void CoinControlDialog::updateView() int nDisplayUnit = model->getOptionsModel()->getDisplayUnit(); double mempoolEstimatePriority = mempool.estimatePriority(nTxConfirmTarget); - map<QString, vector<COutput> > mapCoins; + std::map<QString, std::vector<COutput> > mapCoins; model->listCoins(mapCoins); - BOOST_FOREACH(PAIRTYPE(QString, vector<COutput>) coins, mapCoins) - { + BOOST_FOREACH(const PAIRTYPE(QString, std::vector<COutput>)& coins, mapCoins) { QTreeWidgetItem *itemWalletAddress = new QTreeWidgetItem(); itemWalletAddress->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); QString sWalletAddress = coins.first; @@ -719,8 +718,7 @@ void CoinControlDialog::updateView() double dPrioritySum = 0; int nChildren = 0; int nInputSum = 0; - BOOST_FOREACH(const COutput& out, coins.second) - { + BOOST_FOREACH(const COutput& out, coins.second) { int nInputSize = 0; nSum += out.tx->vout[out.i].nValue; nChildren++; @@ -794,7 +792,7 @@ void CoinControlDialog::updateView() COutPoint outpt(txhash, out.i); coinControl->UnSelect(outpt); // just to be sure itemOutput->setDisabled(true); - itemOutput->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed")); + itemOutput->setIcon(COLUMN_CHECKBOX, platformStyle->SingleColorIcon(":/icons/lock_closed")); } // set checkbox diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 5ec382838f..8ff1eac709 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -16,6 +16,7 @@ #include <QString> #include <QTreeWidgetItem> +class PlatformStyle; class WalletModel; class CCoinControl; @@ -32,7 +33,7 @@ class CoinControlDialog : public QDialog Q_OBJECT public: - explicit CoinControlDialog(QWidget *parent = 0); + explicit CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent = 0); ~CoinControlDialog(); void setModel(WalletModel *model); @@ -57,6 +58,8 @@ private: QAction *lockAction; QAction *unlockAction; + const PlatformStyle *platformStyle; + QString strPad(QString, int, QString); void sortView(int, Qt::SortOrder); void updateView(); @@ -102,7 +105,7 @@ private: return column; } -private slots: +private Q_SLOTS: void showMenu(const QPoint &); void copyAmount(); void copyLabel(); diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h index 13c6da8eda..d59fce2d41 100644 --- a/src/qt/editaddressdialog.h +++ b/src/qt/editaddressdialog.h @@ -40,7 +40,7 @@ public: QString getAddress() const; void setAddress(const QString &address); -public slots: +public Q_SLOTS: void accept(); private: diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/debugwindow.ui index c1eb185501..4117da57f5 100644 --- a/src/qt/forms/rpcconsole.ui +++ b/src/qt/forms/debugwindow.ui @@ -87,6 +87,32 @@ </widget> </item> <item row="3" column="0"> + <widget class="QLabel" name="labelClientUserAgent"> + <property name="text"> + <string>User Agent</string> + </property> + <property name="indent"> + <number>10</number> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="clientUserAgent"> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="text"> + <string>N/A</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="4" column="0"> <widget class="QLabel" name="label_14"> <property name="text"> <string>Using OpenSSL version</string> @@ -96,7 +122,7 @@ </property> </widget> </item> - <item row="3" column="1"> + <item row="4" column="1"> <widget class="QLabel" name="openSSLVersion"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -112,7 +138,7 @@ </property> </widget> </item> - <item row="4" column="0"> + <item row="5" column="0"> <widget class="QLabel" name="label_berkeleyDBVersion"> <property name="text"> <string>Using BerkeleyDB version</string> @@ -122,7 +148,7 @@ </property> </widget> </item> - <item row="4" column="1"> + <item row="5" column="1"> <widget class="QLabel" name="berkeleyDBVersion"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -138,14 +164,14 @@ </property> </widget> </item> - <item row="5" column="0"> + <item row="6" column="0"> <widget class="QLabel" name="label_12"> <property name="text"> <string>Build date</string> </property> </widget> </item> - <item row="5" column="1"> + <item row="6" column="1"> <widget class="QLabel" name="buildDate"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -161,14 +187,14 @@ </property> </widget> </item> - <item row="6" column="0"> + <item row="7" column="0"> <widget class="QLabel" name="label_13"> <property name="text"> <string>Startup time</string> </property> </widget> </item> - <item row="6" column="1"> + <item row="7" column="1"> <widget class="QLabel" name="startupTime"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -184,7 +210,7 @@ </property> </widget> </item> - <item row="7" column="0"> + <item row="8" column="0"> <widget class="QLabel" name="label_11"> <property name="font"> <font> @@ -197,14 +223,14 @@ </property> </widget> </item> - <item row="8" column="0"> + <item row="9" column="0"> <widget class="QLabel" name="label_8"> <property name="text"> <string>Name</string> </property> </widget> </item> - <item row="8" column="1"> + <item row="9" column="1"> <widget class="QLabel" name="networkName"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -220,14 +246,14 @@ </property> </widget> </item> - <item row="9" column="0"> + <item row="10" column="0"> <widget class="QLabel" name="label_7"> <property name="text"> <string>Number of connections</string> </property> </widget> </item> - <item row="9" column="1"> + <item row="10" column="1"> <widget class="QLabel" name="numberOfConnections"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -243,7 +269,7 @@ </property> </widget> </item> - <item row="10" column="0"> + <item row="11" column="0"> <widget class="QLabel" name="label_10"> <property name="font"> <font> @@ -256,14 +282,14 @@ </property> </widget> </item> - <item row="11" column="0"> + <item row="12" column="0"> <widget class="QLabel" name="label_3"> <property name="text"> <string>Current number of blocks</string> </property> </widget> </item> - <item row="11" column="1"> + <item row="12" column="1"> <widget class="QLabel" name="numberOfBlocks"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -279,14 +305,14 @@ </property> </widget> </item> - <item row="12" column="0"> + <item row="13" column="0"> <widget class="QLabel" name="label_2"> <property name="text"> <string>Last block time</string> </property> </widget> </item> - <item row="12" column="1"> + <item row="13" column="1"> <widget class="QLabel" name="lastBlockTime"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -302,7 +328,7 @@ </property> </widget> </item> - <item row="13" column="0"> + <item row="14" column="0"> <spacer name="verticalSpacer_2"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -315,7 +341,7 @@ </property> </spacer> </item> - <item row="14" column="0"> + <item row="15" column="0"> <widget class="QLabel" name="labelDebugLogfile"> <property name="font"> <font> @@ -328,7 +354,7 @@ </property> </widget> </item> - <item row="15" column="0"> + <item row="16" column="0"> <widget class="QPushButton" name="openDebugLogfileButton"> <property name="toolTip"> <string>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</string> @@ -341,7 +367,7 @@ </property> </widget> </item> - <item row="16" column="0"> + <item row="17" column="0"> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -687,17 +713,85 @@ </attribute> <layout class="QGridLayout" name="gridLayout_2"> <item row="0" column="0" rowspan="2"> - <widget class="QTableView" name="peerWidget"> - <property name="horizontalScrollBarPolicy"> - <enum>Qt::ScrollBarAsNeeded</enum> - </property> - <property name="sortingEnabled"> - <bool>true</bool> + <layout class="QVBoxLayout" name="verticalLayout_101"> + <property name="spacing"> + <number>0</number> </property> - <attribute name="horizontalHeaderHighlightSections"> - <bool>false</bool> - </attribute> - </widget> + <item> + <widget class="QTableView" name="peerWidget"> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAsNeeded</enum> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <attribute name="horizontalHeaderHighlightSections"> + <bool>false</bool> + </attribute> + </widget> + </item> + <item> + <widget class="QLabel" name="banHeading"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>300</width> + <height>32</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>32</height> + </size> + </property> + <property name="font"> + <font> + <pointsize>12</pointsize> + </font> + </property> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="text"> + <string>Banned peers</string> + </property> + <property name="alignment"> + <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::NoTextInteraction</set> + </property> + </widget> + </item> + <item> + <widget class="QTableView" name="banlistWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAsNeeded</enum> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <attribute name="horizontalHeaderHighlightSections"> + <bool>false</bool> + </attribute> + </widget> + </item> + </layout> </item> <item row="0" column="1"> <widget class="QLabel" name="peerHeading"> @@ -745,13 +839,36 @@ </property> <layout class="QGridLayout" name="gridLayout_3"> <item row="0" column="0"> + <widget class="QLabel" name="label_30"> + <property name="text"> + <string>Whitelisted</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="peerWhitelisted"> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="text"> + <string>N/A</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="1" column="0"> <widget class="QLabel" name="label_23"> <property name="text"> <string>Direction</string> </property> </widget> </item> - <item row="0" column="2"> + <item row="1" column="2"> <widget class="QLabel" name="peerDirection"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -767,14 +884,14 @@ </property> </widget> </item> - <item row="1" column="0"> + <item row="2" column="0"> <widget class="QLabel" name="label_21"> <property name="text"> <string>Version</string> </property> </widget> </item> - <item row="1" column="2"> + <item row="2" column="2"> <widget class="QLabel" name="peerVersion"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -790,14 +907,14 @@ </property> </widget> </item> - <item row="2" column="0"> + <item row="3" column="0"> <widget class="QLabel" name="label_28"> <property name="text"> <string>User Agent</string> </property> </widget> </item> - <item row="2" column="2"> + <item row="3" column="2"> <widget class="QLabel" name="peerSubversion"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -813,14 +930,14 @@ </property> </widget> </item> - <item row="3" column="0"> + <item row="4" column="0"> <widget class="QLabel" name="label_4"> <property name="text"> <string>Services</string> </property> </widget> </item> - <item row="3" column="2"> + <item row="4" column="2"> <widget class="QLabel" name="peerServices"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -839,7 +956,7 @@ <item row="5" column="0"> <widget class="QLabel" name="label_29"> <property name="text"> - <string>Starting Height</string> + <string>Starting Block</string> </property> </widget> </item> @@ -862,7 +979,7 @@ <item row="6" column="0"> <widget class="QLabel" name="label_27"> <property name="text"> - <string>Sync Height</string> + <string>Synced Headers</string> </property> </widget> </item> @@ -883,13 +1000,36 @@ </widget> </item> <item row="7" column="0"> + <widget class="QLabel" name="label_25"> + <property name="text"> + <string>Synced Blocks</string> + </property> + </widget> + </item> + <item row="7" column="2"> + <widget class="QLabel" name="peerCommonHeight"> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="text"> + <string>N/A</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="8" column="0"> <widget class="QLabel" name="label_24"> <property name="text"> <string>Ban Score</string> </property> </widget> </item> - <item row="7" column="2"> + <item row="8" column="2"> <widget class="QLabel" name="peerBanScore"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -905,14 +1045,14 @@ </property> </widget> </item> - <item row="8" column="0"> + <item row="9" column="0"> <widget class="QLabel" name="label_22"> <property name="text"> <string>Connection Time</string> </property> </widget> </item> - <item row="8" column="2"> + <item row="9" column="2"> <widget class="QLabel" name="peerConnTime"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -928,14 +1068,14 @@ </property> </widget> </item> - <item row="9" column="0"> + <item row="10" column="0"> <widget class="QLabel" name="label_15"> <property name="text"> <string>Last Send</string> </property> </widget> </item> - <item row="9" column="2"> + <item row="10" column="2"> <widget class="QLabel" name="peerLastSend"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -951,14 +1091,14 @@ </property> </widget> </item> - <item row="10" column="0"> + <item row="11" column="0"> <widget class="QLabel" name="label_19"> <property name="text"> <string>Last Receive</string> </property> </widget> </item> - <item row="10" column="2"> + <item row="11" column="2"> <widget class="QLabel" name="peerLastRecv"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -974,14 +1114,14 @@ </property> </widget> </item> - <item row="11" column="0"> + <item row="12" column="0"> <widget class="QLabel" name="label_18"> <property name="text"> <string>Bytes Sent</string> </property> </widget> </item> - <item row="11" column="2"> + <item row="12" column="2"> <widget class="QLabel" name="peerBytesSent"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -997,14 +1137,14 @@ </property> </widget> </item> - <item row="12" column="0"> + <item row="13" column="0"> <widget class="QLabel" name="label_20"> <property name="text"> <string>Bytes Received</string> </property> </widget> </item> - <item row="12" column="2"> + <item row="13" column="2"> <widget class="QLabel" name="peerBytesRecv"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -1020,14 +1160,14 @@ </property> </widget> </item> - <item row="13" column="0"> + <item row="14" column="0"> <widget class="QLabel" name="label_26"> <property name="text"> <string>Ping Time</string> </property> </widget> </item> - <item row="13" column="2"> + <item row="14" column="2"> <widget class="QLabel" name="peerPingTime"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -1043,14 +1183,40 @@ </property> </widget> </item> - <item row="14" column="0"> + <item row="15" column="0"> + <widget class="QLabel" name="peerPingWaitLabel"> + <property name="toolTip"> + <string>The duration of a currently outstanding ping.</string> + </property> + <property name="text"> + <string>Ping Wait</string> + </property> + </widget> + </item> + <item row="15" column="2"> + <widget class="QLabel" name="peerPingWait"> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="text"> + <string>N/A</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="16" column="0"> <widget class="QLabel" name="label_timeoffset"> <property name="text"> <string>Time Offset</string> </property> </widget> </item> - <item row="14" column="2"> + <item row="16" column="2"> <widget class="QLabel" name="timeoffset"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -1066,7 +1232,7 @@ </property> </widget> </item> - <item row="15" column="1"> + <item row="17" column="1"> <spacer name="verticalSpacer_3"> <property name="orientation"> <enum>Qt::Vertical</enum> diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 55c4f5ac58..22c67b8040 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>560</width> - <height>400</height> + <height>440</height> </rect> </property> <property name="windowTitle"> @@ -298,6 +298,193 @@ </layout> </item> <item> + <layout class="QHBoxLayout" name="horizontalLayout_2_Network"> + <item> + <widget class="QLabel" name="proxyActiveNets"> + <property name="text"> + <string>Used for reaching peers via:</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="proxyReachIPv4"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="proxyReachIPv4Label"> + <property name="text"> + <string>IPv4</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="proxyReachIPv6"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="proxyReachIPv6Label"> + <property name="text"> + <string>IPv6</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="proxyReachTor"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="proxyReachTorLabel"> + <property name="text"> + <string>Tor</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2_Network"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QCheckBox" name="connectSocksTor"> + <property name="toolTip"> + <string>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</string> + </property> + <property name="text"> + <string>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3_Network"> + <item> + <widget class="QLabel" name="proxyIpTorLabel"> + <property name="text"> + <string>Proxy &IP:</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + <property name="buddy"> + <cstring>proxyIpTor</cstring> + </property> + </widget> + </item> + <item> + <widget class="QValidatedLineEdit" name="proxyIpTor"> + <property name="minimumSize"> + <size> + <width>140</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>140</width> + <height>16777215</height> + </size> + </property> + <property name="toolTip"> + <string>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="proxyPortTorLabel"> + <property name="text"> + <string>&Port:</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + <property name="buddy"> + <cstring>proxyPortTor</cstring> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="proxyPortTor"> + <property name="minimumSize"> + <size> + <width>55</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>55</width> + <height>16777215</height> + </size> + </property> + <property name="toolTip"> + <string>Port of the proxy (e.g. 9050)</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_4_Network"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> <spacer name="verticalSpacer_Network"> <property name="orientation"> <enum>Qt::Vertical</enum> diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index 53d416ef38..6d792d1475 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -59,21 +59,35 @@ </widget> </item> <item> - <widget class="QLabel" name="labelWalletStatus"> - <property name="cursor"> - <cursorShape>WhatsThisCursor</cursorShape> + <widget class="QPushButton" name="labelWalletStatus"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>16777215</height> + </size> </property> <property name="toolTip"> <string>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.</string> </property> - <property name="styleSheet"> - <string notr="true">QLabel { color: red; }</string> - </property> <property name="text"> - <string notr="true">(out of sync)</string> + <string/> </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + <property name="icon"> + <iconset resource="../bitcoin.qrc"> + <normaloff>:/icons/warning</normaloff> + <disabledoff>:/icons/warning</disabledoff>:/icons/warning</iconset> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> </property> </widget> </item> @@ -431,21 +445,35 @@ </widget> </item> <item> - <widget class="QLabel" name="labelTransactionsStatus"> - <property name="cursor"> - <cursorShape>WhatsThisCursor</cursorShape> + <widget class="QPushButton" name="labelTransactionsStatus"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>16777215</height> + </size> </property> <property name="toolTip"> <string>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.</string> </property> - <property name="styleSheet"> - <string notr="true">QLabel { color: red; }</string> - </property> <property name="text"> - <string notr="true">(out of sync)</string> + <string/> </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <property name="icon"> + <iconset resource="../bitcoin.qrc"> + <normaloff>:/icons/warning</normaloff> + <disabledoff>:/icons/warning</disabledoff>:/icons/warning</iconset> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> </property> </widget> </item> diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui index 48d0dd093c..df06f36833 100644 --- a/src/qt/forms/sendcoinsentry.ui +++ b/src/qt/forms/sendcoinsentry.ui @@ -21,15 +21,21 @@ <string>This is a normal payment.</string> </property> <property name="frameShape"> - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Sunken</enum> + <enum>QFrame::NoFrame</enum> </property> <layout class="QGridLayout" name="gridLayout"> - <property name="spacing"> + <property name="topMargin"> + <number>8</number> + </property> + <property name="bottomMargin"> + <number>4</number> + </property> + <property name="horizontalSpacing"> <number>12</number> </property> + <property name="verticalSpacing"> + <number>8</number> + </property> <item row="0" column="0"> <widget class="QLabel" name="payToLabel"> <property name="text"> @@ -193,6 +199,13 @@ </property> </widget> </item> + <item row="4" column="0" colspan="2"> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> </layout> </widget> <widget class="QFrame" name="SendCoins_UnauthenticatedPaymentRequest"> @@ -618,10 +631,7 @@ <bool>true</bool> </property> <property name="frameShape"> - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Sunken</enum> + <enum>QFrame::NoFrame</enum> </property> <layout class="QGridLayout" name="gridLayout_is"> <property name="spacing"> @@ -1150,10 +1160,7 @@ <bool>true</bool> </property> <property name="frameShape"> - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Sunken</enum> + <enum>QFrame::NoFrame</enum> </property> <layout class="QGridLayout" name="gridLayout_s"> <property name="spacing"> diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index a0a2993ea3..7d3e48ff32 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -42,7 +42,7 @@ static const int MAX_URI_LENGTH = 255; #define EXPORT_IMAGE_SIZE 256 /* Number of frames in spinner animation */ -#define SPINNER_FRAMES 35 +#define SPINNER_FRAMES 36 #define QAPP_ORG_NAME "Bitcoin" #define QAPP_ORG_DOMAIN "bitcoin.org" diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 4a1f728e18..8917f77f22 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -11,7 +11,7 @@ #include "primitives/transaction.h" #include "init.h" -#include "main.h" +#include "main.h" // For minRelayTxFee #include "protocol.h" #include "script/script.h" #include "script/standard.h" @@ -265,6 +265,19 @@ void copyEntryData(QAbstractItemView *view, int column, int role) } } +QString getEntryData(QAbstractItemView *view, int column, int role) +{ + if(!view || !view->selectionModel()) + return QString(); + QModelIndexList selection = view->selectionModel()->selectedRows(column); + + if(!selection.isEmpty()) { + // Return first item + return (selection.at(0).data(role).toString()); + } + return QString(); +} + QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedSuffixOut) @@ -391,7 +404,7 @@ void SubstituteFonts(const QString& language) { #if defined(Q_OS_MAC) // Background: -// OSX's default font changed in 10.9 and QT is unable to find it with its +// OSX's default font changed in 10.9 and Qt is unable to find it with its // usual fallback methods when building against the 10.7 sdk or lower. // The 10.8 SDK added a function to let it find the correct fallback font. // If this fallback is not properly loaded, some characters may fail to diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index bcbb540c37..0ac3db6327 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -64,6 +64,14 @@ namespace GUIUtil */ void copyEntryData(QAbstractItemView *view, int column, int role=Qt::EditRole); + /** Return a field of the currently selected entry as a QString. Does nothing if nothing + is selected. + @param[in] column Data column to extract from the model + @param[in] role Data role to extract from the model + @see TransactionView::copyLabel, TransactionView::copyAmount, TransactionView::copyAddress + */ + QString getEntryData(QAbstractItemView *view, int column, int role); + void setClipboard(const QString& str); /** Get save filename, mimics QFileDialog::getSaveFileName, except that it appends a default suffix @@ -161,7 +169,7 @@ namespace GUIUtil void setViewHeaderResizeMode(int logicalIndex, QHeaderView::ResizeMode resizeMode); void resizeColumn(int nColumnIndex, int width); - private slots: + private Q_SLOTS: void on_sectionResized(int logicalIndex, int oldSize, int newSize); void on_geometriesChanged(); }; @@ -205,7 +213,7 @@ namespace GUIUtil #else typedef QProgressBar ProgressBar; #endif - + } // namespace GUIUtil #endif // BITCOIN_QT_GUIUTIL_H diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 9f72602b4d..4ab87e0f32 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -6,7 +6,6 @@ #include "ui_intro.h" #include "guiutil.h" -#include "scicon.h" #include "util.h" @@ -42,10 +41,10 @@ public: ST_ERROR }; -public slots: +public Q_SLOTS: void check(); -signals: +Q_SIGNALS: void reply(int status, const QString &message, quint64 available); private: @@ -102,7 +101,7 @@ void FreespaceChecker::check() replyStatus = ST_ERROR; replyMessage = tr("Cannot create data directory here."); } - emit reply(replyStatus, replyMessage, freeBytesAvailable); + Q_EMIT reply(replyStatus, replyMessage, freeBytesAvailable); } @@ -121,7 +120,7 @@ Intro::~Intro() { delete ui; /* Ensure thread is finished before it is deleted */ - emit stopThread(); + Q_EMIT stopThread(); thread->wait(); } @@ -168,7 +167,7 @@ void Intro::pickDataDirectory() /* If current default data directory does not exist, let the user choose one */ Intro intro; intro.setDataDirectory(dataDir); - intro.setWindowIcon(SingleColorIcon(":icons/bitcoin")); + intro.setWindowIcon(QIcon(":icons/bitcoin")); while(true) { @@ -277,7 +276,7 @@ void Intro::checkPath(const QString &dataDir) if(!signalled) { signalled = true; - emit requestCheck(); + Q_EMIT requestCheck(); } mutex.unlock(); } diff --git a/src/qt/intro.h b/src/qt/intro.h index c9735615b6..50783f7225 100644 --- a/src/qt/intro.h +++ b/src/qt/intro.h @@ -43,14 +43,14 @@ public: */ static QString getDefaultDataDirectory(); -signals: +Q_SIGNALS: void requestCheck(); void stopThread(); -public slots: +public Q_SLOTS: void setStatus(int status, const QString &message, quint64 bytesAvailable); -private slots: +private Q_SLOTS: void on_dataDirectory_textChanged(const QString &arg1); void on_ellipsisButton_clicked(); void on_dataDirDefault_clicked(); diff --git a/src/qt/locale/bitcoin_ach.ts b/src/qt/locale/bitcoin_ach.ts index 835ddb8eaa..ddb9fb85ce 100644 --- a/src/qt/locale/bitcoin_ach.ts +++ b/src/qt/locale/bitcoin_ach.ts @@ -1,4 +1,4 @@ -<TS language="ach" version="2.1"> +<TS language="ach" version="2.0"> <context> <name>AddressBookPage</name> </context> diff --git a/src/qt/locale/bitcoin_af_ZA.ts b/src/qt/locale/bitcoin_af_ZA.ts index e22591e8c5..3767a4c830 100644 --- a/src/qt/locale/bitcoin_af_ZA.ts +++ b/src/qt/locale/bitcoin_af_ZA.ts @@ -1,4 +1,4 @@ -<TS language="af_ZA" version="2.1"> +<TS language="af_ZA" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -68,10 +68,6 @@ <translation>Verander wagwoord</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Tik asseblief die ou en nuwe wagwoord vir die beursie in.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Bevestig beursie enkripsie.</translation> </message> @@ -485,8 +481,8 @@ <translation>Tipe</translation> </message> <message> - <source>Address</source> - <translation>Adres</translation> + <source>Label</source> + <translation>Etiket</translation> </message> <message> <source>Received with</source> diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index 116a1eea76..e56083fa2c 100644 --- a/src/qt/locale/bitcoin_ar.ts +++ b/src/qt/locale/bitcoin_ar.ts @@ -1,4 +1,4 @@ -<TS language="ar" version="2.1"> +<TS language="ar" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -152,10 +152,6 @@ <translation>تغيير كلمة المرور</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>أدخل كلمة المرور القديمة والجديدة للمحفظة.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>تأكيد تشفير المحفظة</translation> </message> @@ -184,10 +180,6 @@ <translation>أدخل عبارة مرور جديدة إلى المحفظة. الرجاء استخدام عبارة مرور تتكون من10 حروف عشوائية على الاقل, أو أكثر من 7 كلمات</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>بتكوين سوف يغلق الآن لإنهاء عملية التشفير. تذكر أن التشفير لا يستطيع حماية محفظتك تمامًا من السرقة من خلال البرمجيات الخبيثة التي تصيب جهازك </translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>فشل تشفير المحفظة</translation> </message> @@ -300,17 +292,13 @@ </message> <message> <source>Reindexing blocks on disk...</source> - <translation>إعادة فهرسة الكتل على القرص</translation> + <translation>إعادة الفهرسة الكتل على القرص ...</translation> </message> <message> <source>Send coins to a Bitcoin address</source> <translation>ارسل عملات الى عنوان بيتكوين</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>تعديل إعدادات bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>احفظ نسخة احتياطية للمحفظة في مكان آخر</translation> </message> @@ -352,7 +340,7 @@ </message> <message> <source>Encrypt the private keys that belong to your wallet</source> - <translation>تشفير المفتاح الخاص لمحفظتك</translation> + <translation>تشفير المفتاح الخاص بمحفظتك</translation> </message> <message> <source>&File</source> @@ -378,18 +366,6 @@ <source>&About Bitcoin Core</source> <translation>حول bitcoin core</translation> </message> - <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n ساعة</numerusform><numerusform>%n ساعة</numerusform><numerusform>%n ساعة</numerusform><numerusform>%n ساعات</numerusform><numerusform>%n ساعات</numerusform><numerusform>%n ساعات</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n يوم</numerusform><numerusform>%n يوم</numerusform><numerusform>%n يوم</numerusform><numerusform>%n أيام</numerusform><numerusform>%n أيام</numerusform><numerusform>%n ايام</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n week(s)</source> - <translation><numerusform>%n اسبوع</numerusform><numerusform>%n اسبوع</numerusform><numerusform>%n اسبوع</numerusform><numerusform>%n اسابيع</numerusform><numerusform>%n اسابيع</numerusform><numerusform>%n اسابيع</numerusform></translation> - </message> <message> <source>Error</source> <translation>خطأ</translation> @@ -438,11 +414,11 @@ <name>CoinControlDialog</name> <message> <source>Quantity:</source> - <translation>الكمية:</translation> + <translation>الكمية :</translation> </message> <message> <source>Amount:</source> - <translation>القيمة</translation> + <translation>القيمة :</translation> </message> <message> <source>Priority:</source> @@ -482,7 +458,7 @@ </message> <message> <source>Copy address</source> - <translation> انسخ العنوان</translation> + <translation> انسخ عنوان</translation> </message> <message> <source>Copy label</source> @@ -490,15 +466,15 @@ </message> <message> <source>Copy amount</source> - <translation>نسخ القيمة</translation> + <translation>نسخ الكمية</translation> </message> <message> <source>Copy transaction ID</source> - <translation>نسخ رقم المعاملة</translation> + <translation>نسخ رقم العملية</translation> </message> <message> <source>Copy quantity</source> - <translation>نسخ الكمية</translation> + <translation>نسخ الكمية </translation> </message> <message> <source>Copy fee</source> @@ -514,7 +490,7 @@ </message> <message> <source>Copy change</source> - <translation>نسخ التغييرات</translation> + <translation>نسخ التعديل</translation> </message> <message> <source>highest</source> @@ -641,10 +617,6 @@ <source>Usage:</source> <translation>المستخدم</translation> </message> - <message> - <source>UI options</source> - <translation>خيارات UI</translation> - </message> </context> <context> <name>Intro</name> @@ -793,11 +765,7 @@ <source>Your current total balance</source> <translation>رصيدك الكلي الحالي</translation> </message> - <message> - <source>out of sync</source> - <translation>خارج المزامنه</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> </context> @@ -811,10 +779,6 @@ <translation>المبلغ</translation> </message> <message> - <source>UNKNOWN</source> - <translation>غير معروف</translation> - </message> - <message> <source>N/A</source> <translation>غير معروف</translation> </message> @@ -949,7 +913,7 @@ </message> <message> <source>&Label:</source> - <translation>&الوصف:</translation> + <translation>&وصف :</translation> </message> <message> <source>&Message:</source> @@ -985,7 +949,7 @@ </message> <message> <source>Copy amount</source> - <translation>نسخ القيمة</translation> + <translation>نسخ الكمية</translation> </message> </context> <context> @@ -1028,7 +992,7 @@ </message> <message> <source>Message</source> - <translation>رسالة</translation> + <translation>رسالة </translation> </message> </context> <context> @@ -1043,7 +1007,7 @@ </message> <message> <source>Message</source> - <translation>رسالة</translation> + <translation>رسالة </translation> </message> <message> <source>Amount</source> @@ -1134,7 +1098,7 @@ </message> <message> <source>Copy amount</source> - <translation>نسخ القيمة</translation> + <translation>نسخ الكمية</translation> </message> <message> <source>Copy fee</source> @@ -1193,7 +1157,7 @@ </message> <message> <source>Paste address from clipboard</source> - <translation>الصق العنوان من لوحة المفاتيح</translation> + <translation>انسخ العنوان من لوحة المفاتيح</translation> </message> <message> <source>Alt+P</source> @@ -1437,10 +1401,6 @@ <translation>النوع</translation> </message> <message> - <source>Address</source> - <translation>عنوان</translation> - </message> - <message> <source>This block was not received by any other nodes and will probably not be accepted!</source> <translation>لم يتم تلقى هذه الكتلة (Block) من قبل أي العقد الأخرى وربما لن تكون مقبولة!</translation> </message> @@ -1453,6 +1413,10 @@ <translation>غير متصل</translation> </message> <message> + <source>Label</source> + <translation>وصف</translation> + </message> + <message> <source>Received with</source> <translation>استقبل مع</translation> </message> @@ -1489,10 +1453,6 @@ <translation>نوع المعاملات</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>عنوان وجهة المعاملة</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>المبلغ الذي أزيل أو أضيف الى الرصيد</translation> </message> @@ -1723,10 +1683,6 @@ <translation>تحذير</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>تحذير : هذا الاصدار قديم , يتطلب التحديث</translation> - </message> - <message> <source>Upgrade wallet to latest format</source> <translation>تحديث المحفظة للنسخة الاخيرة</translation> </message> diff --git a/src/qt/locale/bitcoin_be_BY.ts b/src/qt/locale/bitcoin_be_BY.ts index a3dd430442..5f7f6f89bf 100644 --- a/src/qt/locale/bitcoin_be_BY.ts +++ b/src/qt/locale/bitcoin_be_BY.ts @@ -1,7 +1,11 @@ -<TS language="be_BY" version="2.1"> +<TS language="be_BY" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Правы клік, каб рэдагаваць адрас ці метку</translation> + </message> + <message> <source>Create a new address</source> <translation>Стварыць новы адрас</translation> </message> @@ -62,10 +66,26 @@ <translation>адрасы Прымання</translation> </message> <message> + <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> + <translation>Тут знаходзяцца Біткойн-адрасы для высылання плацяжоў. Заўсёды спраўджвайце колькасць і адрас прызначэння перад здзяйсненнем транзакцыі.</translation> + </message> + <message> + <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> + <translation>Тут знаходзяцца Біткойн-адрасы для прымання плацяжоў. Пажадана выкарыстоўваць новы адрас для кожнай транзакцыі.</translation> + </message> + <message> + <source>Copy &Label</source> + <translation>Капіяваць Метку</translation> + </message> + <message> <source>&Edit</source> <translation>Рэдагаваць</translation> </message> <message> + <source>Export Address List</source> + <translation>Экспартаваць Спіс Адрасоў</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Коскамі падзелены файл (*.csv)</translation> </message> @@ -73,12 +93,16 @@ <source>Exporting Failed</source> <translation>Экспартаванне няўдалае</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Адбылася памылка падчас спробы захаваць адрас у %1. Паспрабуйце зноў.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> <source>Label</source> - <translation>Пазнака</translation> + <translation>Метка</translation> </message> <message> <source>Address</source> @@ -92,6 +116,10 @@ <context> <name>AskPassphraseDialog</name> <message> + <source>Passphrase Dialog</source> + <translation>Дыялог сакрэтнай фразы</translation> + </message> + <message> <source>Enter passphrase</source> <translation>Увядзіце кодавую фразу</translation> </message> @@ -128,10 +156,6 @@ <translation>Змяніць пароль</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Увядзіце стары і новы пароль да гаманца.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Пацвердзіце шыфраванне гаманца</translation> </message> @@ -144,6 +168,14 @@ <translation>Ці ўпэўненыя вы, што жадаеце зашыфраваць свой гаманец?</translation> </message> <message> + <source>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.</source> + <translation>Bitcoin Core зараз будзе зачынены, каб фіналізаваць працэс шыфравання. Памятайце, што шыфраванне вашага гаманца не гарантуе абсалютную абарону ад магчымасці крадзяжу біткойнаў шкоднымі праграмамі, якія могуць інфікаваць ваш камп'ютар.</translation> + </message> + <message> + <source>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.</source> + <translation>ВАЖНА: Усе папярэднія копіі гаманца варта замяніць новым зашыфраваным файлам. У мэтах бяспекі папярэднія копіі незашыфраванага файла-гаманца стануць неўжывальнымі, калі вы станеце карыстацца новым зашыфраваным гаманцом.</translation> + </message> + <message> <source>Warning: The Caps Lock key is on!</source> <translation>Увага: Caps Lock уключаны!</translation> </message> @@ -152,8 +184,12 @@ <translation>Гаманец зашыфраваны</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin зачыняецца дзеля завяршэння працэсса шыфравання. Памятайце, што шыфраванне гаманца цалкам абараняе вашыя сродкі ад скрадання шкоднымі праграмамі якія могуць пранікнуць у ваш камп'ютар.</translation> + <source>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>.</source> + <translation>Увядзіце новы пароль для гаманца.<br/>Парольная фраза павинна складацца<b> не меньш чым з дзесяці сімвалаў</b>, ці <b>больш чым з васьмі слоў</b>.</translation> + </message> + <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Увядзіце стары пароль і новы пароль для гаманца.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -173,7 +209,7 @@ </message> <message> <source>The passphrase entered for the wallet decryption was incorrect.</source> - <translation>Уведзена пароль дзеля расшыфравання гаманца памылковы</translation> + <translation>Уведзены пароль для расшыфравання гаманца памылковы</translation> </message> <message> <source>Wallet decryption failed</source> @@ -239,10 +275,42 @@ <translation>Зашыфраваць Гаманец...</translation> </message> <message> + <source>&Backup Wallet...</source> + <translation>Стварыць копію гаманца...</translation> + </message> + <message> + <source>&Change Passphrase...</source> + <translation>&Change Passphrase...</translation> + </message> + <message> + <source>&Sending addresses...</source> + <translation>Адрасы дасылання...</translation> + </message> + <message> + <source>&Receiving addresses...</source> + <translation>Адрасы прымання...</translation> + </message> + <message> <source>Open &URI...</source> <translation>Адчыниць &URI...</translation> </message> <message> + <source>Bitcoin Core client</source> + <translation>Bitcoin Core кліент</translation> + </message> + <message> + <source>Importing blocks from disk...</source> + <translation>Імпартуюцца блокі з дыску...</translation> + </message> + <message> + <source>Reindexing blocks on disk...</source> + <translation>Пераіндэксацыя блокаў на дыску...</translation> + </message> + <message> + <source>Send coins to a Bitcoin address</source> + <translation>Даслаць манеты на Біткойн-адрас</translation> + </message> + <message> <source>Backup wallet to another location</source> <translation>Зрабіце копію гаманца ў іншае месца</translation> </message> @@ -255,6 +323,18 @@ <translation>Вакно адладкі</translation> </message> <message> + <source>Open debugging and diagnostic console</source> + <translation>Адкрыць кансоль дыягностыкі і адладкі</translation> + </message> + <message> + <source>&Verify message...</source> + <translation>Праверыць паведамленне...</translation> + </message> + <message> + <source>Bitcoin</source> + <translation>Біткойн</translation> + </message> + <message> <source>Wallet</source> <translation>Гаманец</translation> </message> @@ -267,6 +347,10 @@ <translation>Атрымаць</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>Паказаць інфармацыю аб Bitcoin Core</translation> + </message> + <message> <source>&Show / Hide</source> <translation>&Паказаць / Схаваць</translation> </message> @@ -279,6 +363,14 @@ <translation>Зашыфраваць прыватныя ключы, якия належаць вашаму гаманцу</translation> </message> <message> + <source>Sign messages with your Bitcoin addresses to prove you own them</source> + <translation>Падпісаць паведамленне з дапамогай Біткойн-адраса каб даказаць, што яно належыць вам</translation> + </message> + <message> + <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source> + <translation>Спраўдзіць паведамленне з дапамогай Біткойн-адраса каб даказаць, што яно належыць вам</translation> + </message> + <message> <source>&File</source> <translation>Ф&айл</translation> </message> @@ -290,15 +382,99 @@ <source>&Help</source> <translation>Дапамога</translation> </message> + <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>Request payments (generates QR codes and bitcoin: URIs)</source> + <translation>Запатрабаваць плацёж (генеруецца QR-код для біткойн URI)</translation> + </message> + <message> + <source>&About Bitcoin Core</source> + <translation>Аб Bitcoin Core</translation> + </message> + <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Мадыфікаваць опцыі канфігурацыі Bitcoin Core</translation> + </message> + <message> + <source>Show the list of used sending addresses and labels</source> + <translation>Паказаць спіс адрасоў і метак для дасылання</translation> + </message> + <message> + <source>Show the list of used receiving addresses and labels</source> + <translation>Паказаць спіс адрасоў і метак для прымання</translation> + </message> + <message> + <source>Open a bitcoin: URI or payment request</source> + <translation>Адкрыць біткойн: URI ці запыт плацяжу</translation> + </message> + <message> + <source>&Command-line options</source> + <translation>Опцыі каманднага радка</translation> + </message> + <message> + <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> + <translation>Паказваць даведку Bitcoin Core каб атрымаць спіс магчымых опцый каманднага радка</translation> + </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n актыўнае злучэнне з Bitcoin-сецівам</numerusform><numerusform>%n актыўных злучэнняў з Bitcoin-сецівам</numerusform></translation> + <translation><numerusform>%n актыўнае злучэнне з сецівам Bitcoin</numerusform><numerusform>%n актыўных злучэнняў з сецівам Bitcoin</numerusform><numerusform>%n актыўных злучэнняў з сецівам Bitcoin</numerusform><numerusform>%n актыўных злучэнняў з сецівам Bitcoin</numerusform></translation> + </message> + <message> + <source>No block source available...</source> + <translation>Крыніца блокаў недасяжная...</translation> + </message> + <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Апрацаваны %n блок гісторыі транзакцый.</numerusform><numerusform>Апрацавана %n блокі гісторыі транзакцый.</numerusform><numerusform>Апрацавана %n блокаў гісторыі транзакцый.</numerusform><numerusform>Апрацавана %n блокаў гісторыі транзакцый.</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n гадзіна</numerusform><numerusform>%n гадзіны</numerusform><numerusform>%n гадзін</numerusform><numerusform>%n гадзін</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n дзень</numerusform><numerusform>%n дні</numerusform><numerusform>%n дзён</numerusform><numerusform>%n дзён</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n тыдзень</numerusform><numerusform>%n тыдні</numerusform><numerusform>%n тыдняў</numerusform><numerusform>%n тыдняў</numerusform></translation> + </message> + <message> + <source>%1 and %2</source> + <translation>%1 і %2</translation> + </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n год</numerusform><numerusform>%n гады</numerusform><numerusform>%n гадоў</numerusform><numerusform>%n гадоў</numerusform></translation> + </message> + <message> + <source>%1 behind</source> + <translation>%1 таму</translation> + </message> + <message> + <source>Last received block was generated %1 ago.</source> + <translation>Апошні прыняты блок генераваны %1 таму.</translation> + </message> + <message> + <source>Transactions after this will not yet be visible.</source> + <translation>Транзакцыи пасля гэтай не будуць бачныя.</translation> </message> <message> <source>Error</source> <translation>Памылка</translation> </message> <message> + <source>Warning</source> + <translation>Увага</translation> + </message> + <message> + <source>Information</source> + <translation>Інфармацыя</translation> + </message> + <message> <source>Up to date</source> <translation>Сінхранізавана</translation> </message> @@ -307,26 +483,44 @@ <translation>Наганяем...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Дасланыя транзакцыі</translation> + <source>Date: %1 +</source> + <translation>Дата: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Прынятыя транзакцыі</translation> + <source>Amount: %1 +</source> + <translation>Колькасць: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Дата: %1 -Колькасць: %2 -Тып: %3 -Адрас: %4 + <translation>Тып: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Метка: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Адрас: %1 </translation> </message> <message> + <source>Sent transaction</source> + <translation>Дасланыя транзакцыі</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Прынятыя транзакцыі</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Гаманец <b>зашыфраваны</b> і зараз <b>разблакаваны</b></translation> </message> @@ -337,26 +531,82 @@ Address: %4 </context> <context> <name>ClientModel</name> - </context> + <message> + <source>Network Alert</source> + <translation>Трывога Сеціва</translation> + </message> +</context> <context> <name>CoinControlDialog</name> <message> + <source>Quantity:</source> + <translation>Колькасць:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>Байтаў:</translation> + </message> + <message> <source>Amount:</source> <translation>Колькасць:</translation> </message> <message> + <source>Priority:</source> + <translation>Прыярытэт:</translation> + </message> + <message> + <source>Fee:</source> + <translation>Камісія:</translation> + </message> + <message> + <source>Dust:</source> + <translation>Пыл:</translation> + </message> + <message> + <source>After Fee:</source> + <translation>Пасля камісіі:</translation> + </message> + <message> + <source>(un)select all</source> + <translation>(не)выбраць ўсё</translation> + </message> + <message> + <source>Tree mode</source> + <translation>Рэжым дрэва</translation> + </message> + <message> + <source>List mode</source> + <translation>Рэжым спіса</translation> + </message> + <message> <source>Amount</source> <translation>Колькасць</translation> </message> <message> + <source>Received with label</source> + <translation>Прыняць праз метку</translation> + </message> + <message> + <source>Received with address</source> + <translation>Прыняць праз адрас</translation> + </message> + <message> <source>Date</source> <translation>Дата</translation> </message> <message> + <source>Confirmations</source> + <translation>Пацверджанняў</translation> + </message> + <message> <source>Confirmed</source> <translation>Пацверджана</translation> </message> <message> + <source>Priority</source> + <translation>Прыярытэт</translation> + </message> + <message> <source>Copy address</source> <translation>Капіяваць адрас</translation> </message> @@ -373,6 +623,90 @@ Address: %4 <translation>Капіяваць ID транзакцыі</translation> </message> <message> + <source>Lock unspent</source> + <translation>Замкнуць непатрачанае</translation> + </message> + <message> + <source>Unlock unspent</source> + <translation>Адамкнуць непатрачанае</translation> + </message> + <message> + <source>Copy quantity</source> + <translation>Капіяваць колькасць</translation> + </message> + <message> + <source>Copy fee</source> + <translation>Капіяваць камісію</translation> + </message> + <message> + <source>Copy after fee</source> + <translation>Капіяваць з выняткам камісіі</translation> + </message> + <message> + <source>Copy bytes</source> + <translation>Капіяваць байты</translation> + </message> + <message> + <source>Copy priority</source> + <translation>Капіяваць прыярытэт</translation> + </message> + <message> + <source>Copy dust</source> + <translation>Капіяваць пыл</translation> + </message> + <message> + <source>highest</source> + <translation>найвышэйшы</translation> + </message> + <message> + <source>higher</source> + <translation>вышэйшы</translation> + </message> + <message> + <source>high</source> + <translation>высокі</translation> + </message> + <message> + <source>medium-high</source> + <translation>вышэй сярэдняга</translation> + </message> + <message> + <source>medium</source> + <translation>сярэдні</translation> + </message> + <message> + <source>low-medium</source> + <translation>ніжэй сярэдняга</translation> + </message> + <message> + <source>low</source> + <translation>нізкі</translation> + </message> + <message> + <source>lower</source> + <translation>ніжэйшы</translation> + </message> + <message> + <source>lowest</source> + <translation>найніжэйшы</translation> + </message> + <message> + <source>yes</source> + <translation>так</translation> + </message> + <message> + <source>no</source> + <translation>не</translation> + </message> + <message> + <source>This means a fee of at least %1 per kB is required.</source> + <translation>Гэта значыць патрэбную камісію мінімум %1 на Кб.</translation> + </message> + <message> + <source>Transactions with higher priority are more likely to get included into a block.</source> + <translation>Транзакцыя большага прыярытэту больш прываблівая для ўключэння ў блок.</translation> + </message> + <message> <source>(no label)</source> <translation>непазначаны</translation> </message> @@ -385,7 +719,7 @@ Address: %4 </message> <message> <source>&Label</source> - <translation>Пазнака</translation> + <translation>Метка</translation> </message> <message> <source>&Address</source> @@ -422,10 +756,26 @@ Address: %4 </context> <context> <name>FreespaceChecker</name> + <message> + <source>A new data directory will be created.</source> + <translation>Будзе створаны новы каталог з данымі.</translation> + </message> + <message> + <source>name</source> + <translation>імя</translation> + </message> + <message> + <source>Directory already exists. Add %1 if you intend to create a new directory here.</source> + <translation>Каталог ужо існуе. Дадайце %1 калі вы збіраецеся стварыць тут новы каталог.</translation> + </message> </context> <context> <name>HelpMessageDialog</name> <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + <message> <source>(%1-bit)</source> <translation>(%1-біт)</translation> </message> @@ -434,19 +784,51 @@ Address: %4 <translation>Аб Bitcoin Core</translation> </message> <message> + <source>Command-line options</source> + <translation>Опцыі каманднага радка</translation> + </message> + <message> <source>Usage:</source> <translation>Ужыванне:</translation> </message> - </context> + <message> + <source>command-line options</source> + <translation>опцыі каманднага радка</translation> + </message> +</context> <context> <name>Intro</name> <message> + <source>Welcome</source> + <translation>Вітаем</translation> + </message> + <message> + <source>Welcome to Bitcoin Core.</source> + <translation>Вітаем у Bitcoin Core.</translation> + </message> + <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + <message> <source>Error</source> <translation>Памылка</translation> </message> - </context> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n Гб вольнага месца даступна</numerusform><numerusform>%n Гб вольнага месца даступна</numerusform><numerusform>%n Гб вольнага месца даступна</numerusform><numerusform>%n Гб вольнага месца даступна</numerusform></translation> + </message> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(з %n Гб патрэбна)</numerusform><numerusform>(з %n Гб патрэбна)</numerusform><numerusform>(з %n Гб патрэбна)</numerusform><numerusform>(з %n Гб патрэбна)</numerusform></translation> + </message> +</context> <context> <name>OpenURIDialog</name> + <message> + <source>Open URI</source> + <translation>Адкрыць URI</translation> + </message> </context> <context> <name>OptionsDialog</name> @@ -454,6 +836,10 @@ Address: %4 <source>Options</source> <translation>Опцыі</translation> </message> + <message> + <source>MB</source> + <translation>Мб</translation> + </message> </context> <context> <name>OverviewPage</name> @@ -485,7 +871,7 @@ Address: %4 <name>ReceiveCoinsDialog</name> <message> <source>&Label:</source> - <translation>Пазнака:</translation> + <translation>Метка:</translation> </message> <message> <source>Copy label</source> @@ -508,7 +894,11 @@ Address: %4 </message> <message> <source>Label</source> - <translation>Пазнака</translation> + <translation>Метка</translation> + </message> + <message> + <source>Message</source> + <translation>Паведамленне</translation> </message> </context> <context> @@ -519,7 +909,11 @@ Address: %4 </message> <message> <source>Label</source> - <translation>Пазнака</translation> + <translation>Метка</translation> + </message> + <message> + <source>Message</source> + <translation>Паведамленне</translation> </message> <message> <source>Amount</source> @@ -537,14 +931,38 @@ Address: %4 <translation>Даслаць Манеты</translation> </message> <message> + <source>Quantity:</source> + <translation>Колькасць:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>Байтаў:</translation> + </message> + <message> <source>Amount:</source> <translation>Колькасць:</translation> </message> <message> + <source>Priority:</source> + <translation>Прыярытэт:</translation> + </message> + <message> + <source>Fee:</source> + <translation>Камісія:</translation> + </message> + <message> + <source>After Fee:</source> + <translation>Пасля камісіі:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Даслаць адразу некалькім атрымальнікам</translation> </message> <message> + <source>Dust:</source> + <translation>Пыл:</translation> + </message> + <message> <source>Balance:</source> <translation>Баланс:</translation> </message> @@ -557,10 +975,30 @@ Address: %4 <translation>Пацвердзіць дасыланне манет</translation> </message> <message> + <source>Copy quantity</source> + <translation>Капіяваць колькасць</translation> + </message> + <message> <source>Copy amount</source> <translation>Капіяваць колькасць</translation> </message> <message> + <source>Copy fee</source> + <translation>Капіяваць камісію</translation> + </message> + <message> + <source>Copy after fee</source> + <translation>Капіяваць з выняткам камісіі</translation> + </message> + <message> + <source>Copy bytes</source> + <translation>Капіяваць байты</translation> + </message> + <message> + <source>Copy priority</source> + <translation>Капіяваць прыярытэт</translation> + </message> + <message> <source>The amount to pay must be larger than 0.</source> <translation>Велічыня плацяжу мае быць больш за 0.</translation> </message> @@ -568,6 +1006,10 @@ Address: %4 <source>(no label)</source> <translation>непазначаны</translation> </message> + <message> + <source>Copy dust</source> + <translation>Капіяваць пыл</translation> + </message> </context> <context> <name>SendCoinsEntry</name> @@ -585,7 +1027,7 @@ Address: %4 </message> <message> <source>&Label:</source> - <translation>Пазнака:</translation> + <translation>Метка:</translation> </message> <message> <source>Alt+A</source> @@ -599,7 +1041,11 @@ Address: %4 <source>Alt+P</source> <translation>Alt+P</translation> </message> - </context> + <message> + <source>Memo:</source> + <translation>Памятка:</translation> + </message> +</context> <context> <name>ShutdownWindow</name> </context> @@ -621,6 +1067,10 @@ Address: %4 <context> <name>SplashScreen</name> <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + <message> <source>The Bitcoin Core developers</source> <translation>Распрацоўнікі Bitcoin Core</translation> </message> @@ -631,10 +1081,18 @@ Address: %4 </context> <context> <name>TrafficGraphWidget</name> - </context> + <message> + <source>KB/s</source> + <translation>Кб/с</translation> + </message> +</context> <context> <name>TransactionDesc</name> <message> + <source>%1/offline</source> + <translation>%1/offline</translation> + </message> + <message> <source>%1/unconfirmed</source> <translation>%1/непацверджана</translation> </message> @@ -643,10 +1101,22 @@ Address: %4 <translation>%1 пацверджанняў</translation> </message> <message> + <source>Status</source> + <translation>Статус</translation> + </message> + <message> <source>Date</source> <translation>Дата</translation> </message> <message> + <source>Message</source> + <translation>Паведамленне</translation> + </message> + <message> + <source>Comment</source> + <translation>Каментар</translation> + </message> + <message> <source>Transaction ID</source> <translation>ID</translation> </message> @@ -685,10 +1155,6 @@ Address: %4 <translation>Тып</translation> </message> <message> - <source>Address</source> - <translation>Адрас</translation> - </message> - <message> <source>Confirmed (%1 confirmations)</source> <translation>Пацверджана (%1 пацверджанняў)</translation> </message> @@ -701,6 +1167,10 @@ Address: %4 <translation>Згенеравана, але не прынята</translation> </message> <message> + <source>Label</source> + <translation>Метка</translation> + </message> + <message> <source>Received with</source> <translation>Прынята з</translation> </message> @@ -737,10 +1207,6 @@ Address: %4 <translation>Тып транзакцыі</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Адрас прызначэння транзакцыі.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Колькасць аднятая ці даданая да балансу.</translation> </message> @@ -845,7 +1311,7 @@ Address: %4 </message> <message> <source>Label</source> - <translation>Пазнака</translation> + <translation>Метка</translation> </message> <message> <source>Address</source> @@ -911,14 +1377,106 @@ Address: %4 <translation>Ужываць тэставае сеціва</translation> </message> <message> + <source>Do you want to rebuild the block database now?</source> + <translation>Ці жадаеце вы перабудаваць зараз базу звестак блокаў?</translation> + </message> + <message> + <source>Error initializing block database</source> + <translation>Памылка ініцыялізацыі базвы звестак блокаў</translation> + </message> + <message> + <source>Error initializing wallet database environment %s!</source> + <translation>Памалка ініцыялізацыі асяроддзя базы звестак гаманца %s!</translation> + </message> + <message> + <source>Error loading block database</source> + <translation>Памылка загрузкі базвы звестак блокаў</translation> + </message> + <message> + <source>Error opening block database</source> + <translation>Памылка адчынення базы звестак блокаў</translation> + </message> + <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Памылка: здарылася Фатальная унутраная памылка, глядзі debug.log для падрабязнасцяў</translation> + </message> + <message> + <source>Error: Disk space is low!</source> + <translation>Памылка: Замала вольнага месца на дыску!</translation> + </message> + <message> + <source>Importing...</source> + <translation>Імпартаванне...</translation> + </message> + <message> + <source>Not enough file descriptors available.</source> + <translation>Не хапае файлавых дэскрыптараў.</translation> + </message> + <message> + <source>Use UPnP to map the listening port (default: %u)</source> + <translation>Use UPnP to map the listening port (default: %u)</translation> + </message> + <message> + <source>Verifying blocks...</source> + <translation>Праверка блокаў...</translation> + </message> + <message> + <source>Verifying wallet...</source> + <translation>Праверка гаманца...</translation> + </message> + <message> + <source>Wallet options:</source> + <translation>Опцыі гаманца:</translation> + </message> + <message> + <source>Imports blocks from external blk000??.dat file</source> + <translation>Імпартаванне блокаў з вонкавага blk000??.dat файла</translation> + </message> + <message> + <source>Activating best chain...</source> + <translation>Актывацыя лепшага ланцуга...</translation> + </message> + <message> + <source>Information</source> + <translation>Інфармацыя</translation> + </message> + <message> + <source>RPC server options:</source> + <translation>Опцыі RPC сервера:</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Слаць trace/debug звесткі ў кансоль замест файла debug.log</translation> </message> <message> + <source>Signing transaction failed</source> + <translation>Памылка подпісу транзакцыі</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Стартаваць ммінімізаванай</translation> + </message> + <message> + <source>This is experimental software.</source> + <translation>Гэта эксперыментальная праграма.</translation> + </message> + <message> + <source>Transaction amount too small</source> + <translation>Транзакцыя занадта малая</translation> + </message> + <message> + <source>Transaction too large</source> + <translation>Транзакцыя занадта вялікая</translation> + </message> + <message> <source>Username for JSON-RPC connections</source> <translation>Імя карыстальника для JSON-RPC злучэнняў</translation> </message> <message> + <source>Warning</source> + <translation>Увага</translation> + </message> + <message> <source>Password for JSON-RPC connections</source> <translation>Пароль для JSON-RPC злучэнняў</translation> </message> @@ -963,6 +1521,10 @@ Address: %4 <translation>Загружаем гаманец...</translation> </message> <message> + <source>Cannot downgrade wallet</source> + <translation>Немагчыма рэгрэсаваць гаманец</translation> + </message> + <message> <source>Rescanning...</source> <translation>Перасканаванне...</translation> </message> diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts index 950a5a9a50..e2821dbdef 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -1,7 +1,11 @@ -<TS language="bg" version="2.1"> +<TS language="bg" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Десен клик за промяна на адреса или името</translation> + </message> + <message> <source>Create a new address</source> <translation>Създаване на нов адрес</translation> </message> @@ -11,7 +15,7 @@ </message> <message> <source>Copy the currently selected address to the system clipboard</source> - <translation>Копиране на избрания адрес</translation> + <translation>Копиране на избрания адрес към клипборда</translation> </message> <message> <source>&Copy</source> @@ -23,7 +27,7 @@ </message> <message> <source>&Copy Address</source> - <translation>&Копирай</translation> + <translation>&Копирай адрес</translation> </message> <message> <source>Delete the currently selected address from the list</source> @@ -47,7 +51,7 @@ </message> <message> <source>Choose the address to receive coins with</source> - <translation>Изберете адрес за получаване на монети</translation> + <translation>Изберете адрес, на който ще получавате монети</translation> </message> <message> <source>C&hoose</source> @@ -66,6 +70,10 @@ <translation>Това са адресите на получателите на плащания. Винаги проверявайте размера на сумата и адреса на получателя, преди да изпратите монети.</translation> </message> <message> + <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> + <translation>Това са Вашите Биткойн адреси,благодарение на които ще получавате плащания.Препоръчително е да използвате нови адреси за получаване на всяка транзакция.</translation> + </message> + <message> <source>Copy &Label</source> <translation>Копирай &име</translation> </message> @@ -85,7 +93,11 @@ <source>Exporting Failed</source> <translation>Грешка при изнасянето</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Възникна грешка при опита за запазване на списъка с адреси в %1.Моля опитайте отново.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -104,8 +116,12 @@ <context> <name>AskPassphraseDialog</name> <message> + <source>Passphrase Dialog</source> + <translation>Диалог за паролите</translation> + </message> + <message> <source>Enter passphrase</source> - <translation>Въведи парола</translation> + <translation>Въведете текущата парола</translation> </message> <message> <source>New passphrase</source> @@ -113,11 +129,11 @@ </message> <message> <source>Repeat new passphrase</source> - <translation>Още веднъж</translation> + <translation>Въведете новата парола повторно</translation> </message> <message> <source>Encrypt wallet</source> - <translation>Криптиране на портфейла</translation> + <translation>Шифриране на портфейла</translation> </message> <message> <source>This operation needs your wallet passphrase to unlock the wallet.</source> @@ -129,35 +145,31 @@ </message> <message> <source>This operation needs your wallet passphrase to decrypt the wallet.</source> - <translation>Тази операция изисква Вашата парола за декриптиране на портфейла.</translation> + <translation>Тази операция изисква Вашата парола за дешифриране на портфейла.</translation> </message> <message> <source>Decrypt wallet</source> - <translation>Декриптиране на портфейла</translation> + <translation>Дешифриране на портфейла</translation> </message> <message> <source>Change passphrase</source> <translation>Смяна на паролата</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Въведете текущата и новата парола за портфейла.</translation> - </message> - <message> <source>Confirm wallet encryption</source> - <translation>Потвърждаване на криптирането</translation> + <translation>Потвърдете на шифрирането на портфейла</translation> </message> <message> <source>Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!</source> - <translation>ВНИМАНИЕ: Ако защитите вашият портфейл и изгубите ключовата дума, вие ще <b>ИЗГУБИТЕ ВСИЧКИТЕ СИ БИТКОЙНОВЕ</b>!</translation> + <translation>ВНИМАНИЕ: Ако шифрирате вашият портфейл и изгубите паролата си, <b>ЩЕ ИЗГУБИТЕ ВСИЧКИТЕ СИ БИТКОИНИ</b>!</translation> </message> <message> <source>Are you sure you wish to encrypt your wallet?</source> - <translation>Наистина ли искате да шифрирате портфейла?</translation> + <translation>Наистина ли желаете да шифрирате портфейла си?</translation> </message> <message> <source>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.</source> - <translation>ВАЖНО: Всякакви стари бекъп версии, които сте направили на вашият портфейл трябва да бъдат заменени със ново-генерирания, криптиран портфейл файл. От съображения за сигурност, предишните бекъпи на некриптираните портфейли ще станат неизползваеми веднага щом започнете да използвате новият криптиран портфейл.</translation> + <translation>ВАЖНО: Всички стари запазвания, които сте направили на Вашият портфейл трябва да замените с запазване на новополучения, шифриран портфейл. От съображения за сигурност, предишните запазвания на нешифрирани портфейли ще станат неизползваеми веднага, щом започнете да използвате новият, шифриран портфейл.</translation> </message> <message> <source>Warning: The Caps Lock key is on!</source> @@ -165,19 +177,15 @@ </message> <message> <source>Wallet encrypted</source> - <translation>Портфейлът е криптиран</translation> - </message> - <message> - <source>Bitcoin 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.</source> - <translation>Биткоин ще се затоври сега за да завърши процеса на криптиране. Запомнете, че криптирането на вашия портефейл не може напълно да предпази вашите Бит-монети от кражба чрез зловреден софтуер, инфектирал вашия компютър</translation> + <translation>Портфейлът е шифриран</translation> </message> <message> <source>Wallet encryption failed</source> - <translation>Криптирането беше неуспешно</translation> + <translation>Шифрирането беше неуспешно</translation> </message> <message> <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> - <translation>Криптирането на портфейла беше неуспешно поради неизвестен проблем. Портфейлът не е криптиран.</translation> + <translation>Шифрирането на портфейла беше неуспешно, поради софтуерен проблем. Портфейлът не е шифриран.</translation> </message> <message> <source>The supplied passphrases do not match.</source> @@ -185,15 +193,15 @@ </message> <message> <source>Wallet unlock failed</source> - <translation>Отключването беше неуспешно</translation> + <translation>Неуспешно отключване на портфейла</translation> </message> <message> <source>The passphrase entered for the wallet decryption was incorrect.</source> - <translation>Паролата въведена за декриптиране на портфейла е грешна.</translation> + <translation>Паролата въведена за дешифриране на портфейла е грешна.</translation> </message> <message> <source>Wallet decryption failed</source> - <translation>Декриптирането беше неуспешно</translation> + <translation>Дешифрирането на портфейла беше неуспешно</translation> </message> <message> <source>Wallet passphrase was successfully changed.</source> @@ -215,16 +223,20 @@ <translation>&Баланс</translation> </message> <message> + <source>Node</source> + <translation>Сървър</translation> + </message> + <message> <source>Show general overview of wallet</source> <translation>Обобщена информация за портфейла</translation> </message> <message> <source>&Transactions</source> - <translation>&Трансакции</translation> + <translation>&Транзакции</translation> </message> <message> <source>Browse transaction history</source> - <translation>История на трансакциите</translation> + <translation>История на транзакциите</translation> </message> <message> <source>E&xit</source> @@ -248,7 +260,7 @@ </message> <message> <source>&Encrypt Wallet...</source> - <translation>&Криптиране на портфейла...</translation> + <translation>&Шифриране на портфейла...</translation> </message> <message> <source>&Backup Wallet...</source> @@ -259,6 +271,14 @@ <translation>&Смяна на паролата...</translation> </message> <message> + <source>&Sending addresses...</source> + <translation>&Изпращане на адресите...</translation> + </message> + <message> + <source>&Receiving addresses...</source> + <translation>&Получаване на адресите...</translation> + </message> + <message> <source>Open &URI...</source> <translation>Отвори &URI...</translation> </message> @@ -279,6 +299,14 @@ <translation>Променя паролата за портфейла</translation> </message> <message> + <source>&Debug window</source> + <translation>&Прозорец за отстраняване на грешки</translation> + </message> + <message> + <source>Open debugging and diagnostic console</source> + <translation>Отворете конзолата за диагностика и отстраняване на грешки</translation> + </message> + <message> <source>&Verify message...</source> <translation>&Проверка на съобщение...</translation> </message> @@ -299,14 +327,30 @@ <translation>&Получаване</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>Покажете информация за Биткойн ядрото</translation> + </message> + <message> <source>&Show / Hide</source> - <translation>&Покажи / Скрий</translation> + <translation>&Показване / Скриване</translation> </message> <message> <source>Show or hide the main Window</source> <translation>Показване и скриване на основния прозорец</translation> </message> <message> + <source>Encrypt the private keys that belong to your wallet</source> + <translation>Шифроване на личните ключове,които принадлежат на портфейла Ви.</translation> + </message> + <message> + <source>Sign messages with your Bitcoin addresses to prove you own them</source> + <translation>Пишете съобщения със своя Биткойн адрес за да докажете,че е ваш.</translation> + </message> + <message> + <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source> + <translation>Потвърждаване на съобщения за да се знае,че са написани с дадените Биткойн адреси.</translation> + </message> + <message> <source>&File</source> <translation>&Файл</translation> </message> @@ -323,32 +367,52 @@ <translation>Раздели</translation> </message> <message> + <source>Bitcoin Core</source> + <translation>Биткойн ядро</translation> + </message> + <message> + <source>Request payments (generates QR codes and bitcoin: URIs)</source> + <translation>Изискване на плащания(генерира QR кодове и биткойн: URIs)</translation> + </message> + <message> <source>&About Bitcoin Core</source> <translation>&Относно Bitcoin Core</translation> </message> - <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n връзка към Биткоин мрежата</numerusform><numerusform>%n връзки към Биткоин мрежата</numerusform></translation> + <message> + <source>Show the list of used sending addresses and labels</source> + <translation>Показване на списъка с използвани адреси и имена</translation> + </message> + <message> + <source>Show the list of used receiving addresses and labels</source> + <translation>Покажи списък с използваните адреси и имена.</translation> + </message> + <message> + <source>Open a bitcoin: URI or payment request</source> + <translation>Отворете биткойн: URI или заявка за плащане</translation> </message> - <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n час</numerusform><numerusform>%n часа</numerusform></translation> + <message> + <source>&Command-line options</source> + <translation>&Налични команди</translation> </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n ден</numerusform><numerusform>%n дни</numerusform></translation> + <message> + <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> + <translation>Покажи помощните съобщения на Биткойн за да видиш наличните и валидни команди</translation> </message> - <message numerus="yes"> - <source>%n week(s)</source> - <translation><numerusform>%n седмица</numerusform><numerusform>%n седмици</numerusform></translation> + <message> + <source>No block source available...</source> + <translation>Липсва източник на блоковете...</translation> </message> <message> <source>%1 and %2</source> <translation>%1 и %2</translation> </message> - <message numerus="yes"> - <source>%n year(s)</source> - <translation><numerusform>%n година</numerusform><numerusform>%n години</numerusform></translation> + <message> + <source>%1 behind</source> + <translation>%1 зад</translation> + </message> + <message> + <source>Transactions after this will not yet be visible.</source> + <translation>Транзакции след това няма все още да бъдат видими.</translation> </message> <message> <source>Error</source> @@ -360,7 +424,7 @@ </message> <message> <source>Information</source> - <translation>Данни</translation> + <translation>Информация</translation> </message> <message> <source>Up to date</source> @@ -372,23 +436,11 @@ </message> <message> <source>Sent transaction</source> - <translation>Изходяща трансакция</translation> + <translation>Изходяща транзакция</translation> </message> <message> <source>Incoming transaction</source> - <translation>Входяща трансакция</translation> - </message> - <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Дата: %1 -Сума: %2 -Вид: %3 -Адрес: %4 -</translation> + <translation>Входяща транзакция</translation> </message> <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> @@ -401,10 +453,22 @@ Address: %4 </context> <context> <name>ClientModel</name> - </context> + <message> + <source>Network Alert</source> + <translation>Мрежови проблем</translation> + </message> +</context> <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>Избор на монета</translation> + </message> + <message> + <source>Quantity:</source> + <translation>Количество:</translation> + </message> + <message> <source>Bytes:</source> <translation>Байтове:</translation> </message> @@ -421,10 +485,42 @@ Address: %4 <translation>Такса:</translation> </message> <message> + <source>Dust:</source> + <translation>Прах:</translation> + </message> + <message> + <source>After Fee:</source> + <translation>След прилагане на ДДС</translation> + </message> + <message> + <source>Change:</source> + <translation>Ресто</translation> + </message> + <message> + <source>(un)select all</source> + <translation>(Пре)махни всички</translation> + </message> + <message> + <source>Tree mode</source> + <translation>Дървовиден режим</translation> + </message> + <message> + <source>List mode</source> + <translation>Списъчен режим</translation> + </message> + <message> <source>Amount</source> <translation>Сума</translation> </message> <message> + <source>Received with label</source> + <translation>Получени с име</translation> + </message> + <message> + <source>Received with address</source> + <translation>Получени с адрес</translation> + </message> + <message> <source>Date</source> <translation>Дата</translation> </message> @@ -457,6 +553,82 @@ Address: %4 <translation>Копирай транзакция с ID</translation> </message> <message> + <source>Lock unspent</source> + <translation>Заключване на неизхарченото</translation> + </message> + <message> + <source>Unlock unspent</source> + <translation>Отключване на неизхарченото</translation> + </message> + <message> + <source>Copy quantity</source> + <translation>Копиране на количеството</translation> + </message> + <message> + <source>Copy fee</source> + <translation>Копиране на данък добавена стойност</translation> + </message> + <message> + <source>Copy after fee</source> + <translation>Копиране след прилагане на данък добавена стойност</translation> + </message> + <message> + <source>Copy bytes</source> + <translation>Копиране на байтовете</translation> + </message> + <message> + <source>Copy priority</source> + <translation>Копиране на приоритет</translation> + </message> + <message> + <source>Copy dust</source> + <translation>Копирай прахта:</translation> + </message> + <message> + <source>Copy change</source> + <translation>Копирай рестото</translation> + </message> + <message> + <source>highest</source> + <translation>Най-висок</translation> + </message> + <message> + <source>higher</source> + <translation>По-висок</translation> + </message> + <message> + <source>high</source> + <translation>Висок</translation> + </message> + <message> + <source>medium-high</source> + <translation>Средно-висок</translation> + </message> + <message> + <source>medium</source> + <translation>Среден</translation> + </message> + <message> + <source>low-medium</source> + <translation>Ниско-среден</translation> + </message> + <message> + <source>low</source> + <translation>Нисък</translation> + </message> + <message> + <source>lower</source> + <translation>По-нисък</translation> + </message> + <message> + <source>lowest</source> + <translation>Най-нисък</translation> + </message> + <message> + <source>(%1 locked)</source> + <translation>(%1 заключен)</translation> + </message> + <message> <source>none</source> <translation>нищо</translation> </message> @@ -469,14 +641,22 @@ Address: %4 <translation>не</translation> </message> <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Това наименование се оцветява в червено, ако произволен получател получи сума по-малка от %1.</translation> + <source>This means a fee of at least %1 per kB is required.</source> + <translation>Това означава че се изисква такса от поне %1 на килобайт.</translation> + </message> + <message> + <source>Can vary +/- 1 byte per input.</source> + <translation>Може да варира с +-1 байт</translation> </message> <message> <source>(no label)</source> <translation>(без име)</translation> </message> <message> + <source>change from %1 (%2)</source> + <translation>ресто от %1 (%2)</translation> + </message> + <message> <source>(change)</source> <translation>(промени)</translation> </message> @@ -505,11 +685,11 @@ Address: %4 </message> <message> <source>Edit receiving address</source> - <translation>Редактиране на входящ адрес</translation> + <translation>Редактиране на адрес за получаване</translation> </message> <message> <source>Edit sending address</source> - <translation>Редактиране на изходящ адрес</translation> + <translation>Редактиране на адрес за изпращане</translation> </message> <message> <source>The entered address "%1" is already in the address book.</source> @@ -539,13 +719,25 @@ Address: %4 <translation>име</translation> </message> <message> + <source>Directory already exists. Add %1 if you intend to create a new directory here.</source> + <translation>Директорията вече съществува.Добавете %1 ако желаете да добавите нова директория тук.</translation> + </message> + <message> <source>Path already exists, and is not a directory.</source> <translation>Пътят вече съществува и не е папка.</translation> </message> - </context> + <message> + <source>Cannot create data directory here.</source> + <translation>Не може да се създаде директория тук.</translation> + </message> +</context> <context> <name>HelpMessageDialog</name> <message> + <source>Bitcoin Core</source> + <translation>Биткойн ядро</translation> + </message> + <message> <source>version</source> <translation>версия</translation> </message> @@ -555,17 +747,21 @@ Address: %4 </message> <message> <source>About Bitcoin Core</source> - <translation>За Bitcoin Core</translation> + <translation>Относно Bitcoin Core</translation> + </message> + <message> + <source>Command-line options</source> + <translation>Списък с команди</translation> </message> <message> <source>Usage:</source> <translation>Използване:</translation> </message> <message> - <source>UI options</source> - <translation>UI Опции</translation> + <source>command-line options</source> + <translation>Списък с налични команди</translation> </message> - </context> +</context> <context> <name>Intro</name> <message> @@ -573,12 +769,36 @@ Address: %4 <translation>Добре дошли</translation> </message> <message> + <source>Welcome to Bitcoin Core.</source> + <translation>Добре дошли в Биткойн ядрото.</translation> + </message> + <message> + <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source> + <translation>Тъй като това е първото стартиране на програмата можете да изберете къде Биткон ядрото да запази данните си.</translation> + </message> + <message> + <source>Use the default data directory</source> + <translation>Използване на директория по подразбиране</translation> + </message> + <message> + <source>Use a custom data directory:</source> + <translation>Използване на директория ръчно</translation> + </message> + <message> + <source>Bitcoin Core</source> + <translation>Биткойн ядро</translation> + </message> + <message> <source>Error</source> <translation>Грешка</translation> </message> </context> <context> <name>OpenURIDialog</name> + <message> + <source>Open URI</source> + <translation>Отваряне на URI</translation> + </message> </context> <context> <name>OptionsDialog</name> @@ -591,14 +811,34 @@ Address: %4 <translation>&Основни</translation> </message> <message> - <source>&Start Bitcoin on system login</source> - <translation>&Пускане на Биткоин при вход в системата</translation> + <source>Size of &database cache</source> + <translation>Размер на кеша в &базата данни</translation> + </message> + <message> + <source>MB</source> + <translation>Мегабайта</translation> + </message> + <message> + <source>Accept connections from outside</source> + <translation>Приемай връзки отвън</translation> + </message> + <message> + <source>Allow incoming connections</source> + <translation>Позволи входящите връзки</translation> </message> <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>IP адрес на прокси (напр. за IPv4: 127.0.0.1 / за IPv6: ::1)</translation> </message> <message> + <source>Third party transaction URLs</source> + <translation>URL адреси на трети страни</translation> + </message> + <message> + <source>Reset all client options to default.</source> + <translation>Възстановете всички настройки по подразбиране.</translation> + </message> + <message> <source>&Reset Options</source> <translation>&Нулирай настройките</translation> </message> @@ -615,6 +855,10 @@ Address: %4 <translation>Експерт</translation> </message> <message> + <source>&Spend unconfirmed change</source> + <translation>&Похарчете непотвърденото ресто</translation> + </message> + <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> <translation>Автоматично отваряне на входящия Bitcoin порт. Работи само с рутери поддържащи UPnP.</translation> </message> @@ -623,6 +867,14 @@ Address: %4 <translation>Отваряне на входящия порт чрез &UPnP</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Свързване с Биткойн мрежата чрез SOCKS5 прокси.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Свързване чрез SOCKS5 прокси (прокси по подразбиране):</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>Прокси & АйПи:</translation> </message> @@ -647,10 +899,6 @@ Address: %4 <translation>&Минимизиране в системния трей</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>При затваряне на прозореца приложението остава минимизирано. Ако изберете тази опция, приложението може да се затвори само чрез Изход в менюто.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>М&инимизиране при затваряне</translation> </message> @@ -663,18 +911,18 @@ Address: %4 <translation>Език:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Промяната на езика ще влезе в сила след рестартиране на Биткоин.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> - <translation>Мерни единици:</translation> + <translation>Мерна единица за показваните суми:</translation> </message> <message> <source>Choose the default subdivision unit to show in the interface and when sending coins.</source> <translation>Изберете единиците, показвани по подразбиране в интерфейса.</translation> </message> <message> + <source>Whether to show coin control features or not.</source> + <translation>Дали да покаже възможностите за контрол на монетите или не.</translation> + </message> + <message> <source>&OK</source> <translation>ОК</translation> </message> @@ -691,29 +939,57 @@ Address: %4 <translation>нищо</translation> </message> <message> + <source>Confirm options reset</source> + <translation>Потвърдете отмяната на настройките.</translation> + </message> + <message> + <source>Client restart required to activate changes.</source> + <translation>Изисква се рестартиране на клиента за активиране на извършените промени.</translation> + </message> + <message> + <source>This change would require a client restart.</source> + <translation>Тази промяна изисква рестартиране на клиента Ви.</translation> + </message> + <message> <source>The supplied proxy address is invalid.</source> - <translation>Прокси адресът е невалиден.</translation> + <translation>Текущият прокси адрес е невалиден.</translation> </message> </context> <context> <name>OverviewPage</name> <message> <source>Form</source> - <translation>Форма</translation> + <translation>Формуляр</translation> </message> <message> <source>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source> <translation>Текущата информация на екрана може да не е актуална. Вашият портфейл ще се синхронизира автоматично с мрежата на Биткоин, щом поне една връзката с нея се установи; този процес все още не е приключил.</translation> </message> <message> + <source>Watch-only:</source> + <translation>В наблюдателен режим:</translation> + </message> + <message> <source>Available:</source> <translation>Налично:</translation> </message> <message> + <source>Your current spendable balance</source> + <translation>Вашата текуща сметка за изразходване</translation> + </message> + <message> <source>Pending:</source> <translation>Изчакващо:</translation> </message> <message> + <source>Immature:</source> + <translation>Неразвит:</translation> + </message> + <message> + <source>Mined balance that has not yet matured</source> + <translation>Миниран баланс,който все още не се е развил</translation> + </message> + <message> <source>Balances</source> <translation>Баланс</translation> </message> @@ -726,24 +1002,84 @@ Address: %4 <translation>Текущият ви общ баланс</translation> </message> <message> - <source>out of sync</source> - <translation>несинхронизиран</translation> + <source>Spendable:</source> + <translation>За харчене:</translation> </message> -</context> + <message> + <source>Recent transactions</source> + <translation>Скорошни транзакции</translation> + </message> + </context> <context> <name>PaymentServer</name> <message> + <source>URI handling</source> + <translation>Справяне с URI</translation> + </message> + <message> + <source>Invalid payment address %1</source> + <translation>Невалиден адрес на плащане %1</translation> + </message> + <message> + <source>Payment request rejected</source> + <translation>Заявката за плащане беше отхвърлена</translation> + </message> + <message> + <source>Payment request network doesn't match client network.</source> + <translation>Мрежата от която се извършва заявката за плащане не съвпада с мрежата на клиента.</translation> + </message> + <message> <source>Requested payment amount of %1 is too small (considered dust).</source> <translation>Заявената сума за плащане: %1 е твърде малка (счита се за отпадък)</translation> </message> <message> + <source>Payment request error</source> + <translation>Възникна грешка по време назаявката за плащане</translation> + </message> + <message> + <source>Cannot start bitcoin: click-to-pay handler</source> + <translation>Биткойн не можe да се стартира: click-to-pay handler</translation> + </message> + <message> + <source>Payment request file handling</source> + <translation>Файл за справяне със заявки</translation> + </message> + <message> + <source>Refund from %1</source> + <translation>Възстановяване на сума от %1</translation> + </message> + <message> + <source>Payment request DoS protection</source> + <translation>Дос защита на заявката за плащане</translation> + </message> + <message> + <source>Error communicating with %1: %2</source> + <translation>Грешка при комуникацията с %1: %2</translation> + </message> + <message> + <source>Bad response from server %1</source> + <translation>Възникна проблем при свързването със сървър %1</translation> + </message> + <message> <source>Payment acknowledged</source> - <translation>Плащането е приета</translation> + <translation>Плащането е прието</translation> </message> - </context> + <message> + <source>Network request error</source> + <translation>Грешка в мрежата по време на заявката</translation> + </message> +</context> <context> <name>PeerTableModel</name> - </context> + <message> + <source>User Agent</source> + <translation>Клиент на потребителя</translation> + </message> + <message> + <source>Ping Time</source> + <translation>Време за отговор</translation> + </message> +</context> <context> <name>QObject</name> <message> @@ -751,10 +1087,38 @@ Address: %4 <translation>Сума</translation> </message> <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>Въведете Биткойн адрес (например: %1)</translation> + </message> + <message> + <source>%1 d</source> + <translation>%1 ден</translation> + </message> + <message> + <source>%1 h</source> + <translation>%1 час</translation> + </message> + <message> + <source>%1 m</source> + <translation>%1 минута</translation> + </message> + <message> + <source>%1 s</source> + <translation>%1 секунда</translation> + </message> + <message> + <source>None</source> + <translation>Неналичен</translation> + </message> + <message> <source>N/A</source> - <translation>N/A</translation> + <translation>Несъществуващ</translation> </message> - </context> + <message> + <source>%1 ms</source> + <translation>%1 милисекунда</translation> + </message> +</context> <context> <name>QRImageWidget</name> <message> @@ -782,7 +1146,7 @@ Address: %4 </message> <message> <source>N/A</source> - <translation>N/A</translation> + <translation>Несъществуващ</translation> </message> <message> <source>Client version</source> @@ -793,6 +1157,10 @@ Address: %4 <translation>Данни</translation> </message> <message> + <source>Debug window</source> + <translation>Прозорец с грешки</translation> + </message> + <message> <source>General</source> <translation>Основни</translation> </message> @@ -801,6 +1169,14 @@ Address: %4 <translation>Използване на OpenSSL версия</translation> </message> <message> + <source>Using BerkeleyDB version</source> + <translation>Използване на база данни BerkeleyDB </translation> + </message> + <message> + <source>Startup time</source> + <translation>Време за стартиране</translation> + </message> + <message> <source>Network</source> <translation>Мрежа</translation> </message> @@ -833,10 +1209,50 @@ Address: %4 <translation>Избери пиър за детайлна информация.</translation> </message> <message> + <source>Direction</source> + <translation>Посока</translation> + </message> + <message> <source>Version</source> <translation>Версия</translation> </message> <message> + <source>User Agent</source> + <translation>Клиент на потребителя</translation> + </message> + <message> + <source>Services</source> + <translation>Услуги</translation> + </message> + <message> + <source>Starting Height</source> + <translation>Стартова височина</translation> + </message> + <message> + <source>Connection Time</source> + <translation>Продължителност на връзката</translation> + </message> + <message> + <source>Last Send</source> + <translation>Изпратени за последно</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Получени за последно</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Изпратени байтове</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Получени байтове</translation> + </message> + <message> + <source>Ping Time</source> + <translation>Време за отговор</translation> + </message> + <message> <source>Last block time</source> <translation>Време на последния блок</translation> </message> @@ -861,8 +1277,20 @@ Address: %4 <translation>Общо:</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Отворете Биткой дебъг лог файла от настоящата Data папка. Може да отнеме няколко секунди при по - големи лог файлове.</translation> + <source>In:</source> + <translation>Входящи:</translation> + </message> + <message> + <source>Out:</source> + <translation>Изходящи</translation> + </message> + <message> + <source>Build date</source> + <translation>Дата на създаване</translation> + </message> + <message> + <source>Debug log file</source> + <translation>Лог файл,съдържащ грешките</translation> </message> <message> <source>Clear console</source> @@ -872,7 +1300,51 @@ Address: %4 <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Използвайте стрелки надолу и нагореза разглеждане на историятаот команди и <b>Ctrl-L</b> за изчистване на конзолата.</translation> </message> - </context> + <message> + <source>Type <b>help</b> for an overview of available commands.</source> + <translation>Въведeте </b>помощ</b> за да видите наличните команди.</translation> + </message> + <message> + <source>%1 B</source> + <translation>%1 Байт</translation> + </message> + <message> + <source>%1 KB</source> + <translation>%1 Килобайт</translation> + </message> + <message> + <source>%1 MB</source> + <translation>%1 Мегабайт</translation> + </message> + <message> + <source>%1 GB</source> + <translation>%1 Гигабайт</translation> + </message> + <message> + <source>via %1</source> + <translation>посредством %1</translation> + </message> + <message> + <source>never</source> + <translation>Никога</translation> + </message> + <message> + <source>Inbound</source> + <translation>Входящи</translation> + </message> + <message> + <source>Outbound</source> + <translation>Изходящи</translation> + </message> + <message> + <source>Unknown</source> + <translation>Неизвестен</translation> + </message> + <message> + <source>Fetching...</source> + <translation>Прихващане...</translation> + </message> +</context> <context> <name>ReceiveCoinsDialog</name> <message> @@ -884,6 +1356,10 @@ Address: %4 <translation>&Име:</translation> </message> <message> + <source>&Message:</source> + <translation>&Съобщение:</translation> + </message> + <message> <source>Use this form to request payments. All fields are <b>optional</b>.</source> <translation>Използвате този формуляр за заявяване на плащания. Всички полета са <b>незадължителни</b>.</translation> </message> @@ -900,6 +1376,14 @@ Address: %4 <translation>Изчистване</translation> </message> <message> + <source>Requested payments history</source> + <translation>Изискана история на плащанията</translation> + </message> + <message> + <source>&Request payment</source> + <translation>&Изискване на плащане</translation> + </message> + <message> <source>Show</source> <translation>Показване</translation> </message> @@ -923,6 +1407,14 @@ Address: %4 <context> <name>ReceiveRequestDialog</name> <message> + <source>QR Code</source> + <translation>QR код</translation> + </message> + <message> + <source>Copy &URI</source> + <translation>Копиране на &URI</translation> + </message> + <message> <source>Copy &Address</source> <translation>&Копирай адрес</translation> </message> @@ -931,6 +1423,10 @@ Address: %4 <translation>&Запиши изображение...</translation> </message> <message> + <source>Request payment to %1</source> + <translation>Изискване на плащане от %1</translation> + </message> + <message> <source>Payment information</source> <translation>Данни за плащането</translation> </message> @@ -978,6 +1474,10 @@ Address: %4 <translation>(без име)</translation> </message> <message> + <source>(no message)</source> + <translation>(без съобщение)</translation> + </message> + <message> <source>(no amount)</source> <translation>(липсва сума)</translation> </message> @@ -989,6 +1489,22 @@ Address: %4 <translation>Изпращане</translation> </message> <message> + <source>Coin Control Features</source> + <translation>Настройки за контрол на монетите</translation> + </message> + <message> + <source>automatically selected</source> + <translation>астоматично избран</translation> + </message> + <message> + <source>Insufficient funds!</source> + <translation>Нямате достатъчно налични пари!</translation> + </message> + <message> + <source>Quantity:</source> + <translation>Количество:</translation> + </message> + <message> <source>Bytes:</source> <translation>Байтове:</translation> </message> @@ -1005,6 +1521,54 @@ Address: %4 <translation>Такса:</translation> </message> <message> + <source>After Fee:</source> + <translation>След прилагане на ДДС</translation> + </message> + <message> + <source>Change:</source> + <translation>Ресто</translation> + </message> + <message> + <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source> + <translation>Ако тази опция е активирана,но адресът на промяна е празен или невалиден,промяната ще бъде изпратена на новосъздаден адрес.</translation> + </message> + <message> + <source>Transaction Fee:</source> + <translation>Такса за транзакцията:</translation> + </message> + <message> + <source>Choose...</source> + <translation>Избери...</translation> + </message> + <message> + <source>per kilobyte</source> + <translation>за килобайт</translation> + </message> + <message> + <source>total at least</source> + <translation>Крайна сума поне</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Препоръчителна:</translation> + </message> + <message> + <source>Custom:</source> + <translation>По избор:</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Време за потвърждение:</translation> + </message> + <message> + <source>normal</source> + <translation>нормален</translation> + </message> + <message> + <source>fast</source> + <translation>бърз</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Изпращане към повече от един получател</translation> </message> @@ -1017,6 +1581,10 @@ Address: %4 <translation>Изчисти всички полета от формуляра.</translation> </message> <message> + <source>Dust:</source> + <translation>Прах:</translation> + </message> + <message> <source>Clear &All</source> <translation>&Изчисти</translation> </message> @@ -1037,10 +1605,34 @@ Address: %4 <translation>Потвърждаване</translation> </message> <message> + <source>Copy quantity</source> + <translation>Копиране на количеството</translation> + </message> + <message> <source>Copy amount</source> <translation>Копирай сума</translation> </message> <message> + <source>Copy fee</source> + <translation>Копиране на данък добавена стойност</translation> + </message> + <message> + <source>Copy after fee</source> + <translation>Копиране след прилагане на данък добавена стойност</translation> + </message> + <message> + <source>Copy bytes</source> + <translation>Копиране на байтовете</translation> + </message> + <message> + <source>Copy priority</source> + <translation>Копиране на приоритет</translation> + </message> + <message> + <source>Copy change</source> + <translation>Копирай рестото</translation> + </message> + <message> <source>Total Amount %1 (= %2)</source> <translation>Пълна сума %1 (= %2)</translation> </message> @@ -1049,10 +1641,6 @@ Address: %4 <translation>или</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Невалиден адрес на получателя.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Сумата трябва да е по-голяма от 0.</translation> </message> @@ -1061,20 +1649,40 @@ Address: %4 <translation>Сумата надвишава текущия баланс</translation> </message> <message> + <source>The total exceeds your balance when the %1 transaction fee is included.</source> + <translation>Сумата при добавяне на данък добавена стойност по %1 транзакцията надвишава сумата по вашата сметка.</translation> + </message> + <message> <source>Transaction creation failed!</source> - <translation>Грешка при създаването на трансакция!</translation> + <translation>Грешка при създаването на транзакция!</translation> + </message> + <message> + <source>Pay only the minimum fee of %1</source> + <translation>Платете минималната такса от %1</translation> + </message> + <message> + <source>Warning: Invalid Bitcoin address</source> + <translation>Внимание: Невалиден Биткойн адрес</translation> </message> <message> <source>(no label)</source> <translation>(без име)</translation> </message> <message> + <source>Warning: Unknown change address</source> + <translation>Внимание:Неизвестен адрес за промяна</translation> + </message> + <message> + <source>Copy dust</source> + <translation>Копирай прахта:</translation> + </message> + <message> <source>Are you sure you want to send?</source> <translation>Наистина ли искате да изпратите?</translation> </message> <message> <source>added as transaction fee</source> - <translation>добавено като такса за трансакция</translation> + <translation>добавено като такса за транзакция</translation> </message> </context> <context> @@ -1127,10 +1735,22 @@ Address: %4 <source>Pay To:</source> <translation>Плащане на:</translation> </message> - </context> + <message> + <source>Memo:</source> + <translation>Бележка:</translation> + </message> +</context> <context> <name>ShutdownWindow</name> - </context> + <message> + <source>Bitcoin Core is shutting down...</source> + <translation>Биткойн ядрото се изключва...</translation> + </message> + <message> + <source>Do not shut down the computer until this window disappears.</source> + <translation>Не изключвайте компютъра докато този прозорец не изчезне.</translation> + </message> +</context> <context> <name>SignVerifyMessageDialog</name> <message> @@ -1142,10 +1762,6 @@ Address: %4 <translation>&Подпиши</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Можете да подпишете съобщение като доказателство, че притежавате определен адрес. Бъдете внимателни и не подписвайте съобщения, които биха разкрили лична информация без вашето съгласие.</translation> - </message> - <message> <source>Choose previously used address</source> <translation>Изберете използван преди адрес</translation> </message> @@ -1194,6 +1810,10 @@ Address: %4 <translation>Проверете съобщение, за да сте сигурни че е подписано с определен Биткоин адрес</translation> </message> <message> + <source>Verify &Message</source> + <translation>Потвърди &съобщението</translation> + </message> + <message> <source>Click "Sign Message" to generate signature</source> <translation>Натиснете "Подписване на съобщение" за да създадете подпис</translation> </message> @@ -1215,11 +1835,11 @@ Address: %4 </message> <message> <source>Private key for the entered address is not available.</source> - <translation>Не е наличен частният ключ за въведеният адрес.</translation> + <translation>Не е наличен частен ключ за въведеният адрес.</translation> </message> <message> <source>Message signing failed.</source> - <translation>Подписването на съобщение бе неуспешно.</translation> + <translation>Подписването на съобщение беше неуспешно.</translation> </message> <message> <source>Message signed.</source> @@ -1249,6 +1869,10 @@ Address: %4 <context> <name>SplashScreen</name> <message> + <source>Bitcoin Core</source> + <translation>Биткойн ядро</translation> + </message> + <message> <source>The Bitcoin Core developers</source> <translation>Разработчици на Bitcoin Core</translation> </message> @@ -1259,7 +1883,11 @@ Address: %4 </context> <context> <name>TrafficGraphWidget</name> - </context> + <message> + <source>KB/s</source> + <translation>Килобайта в секунда</translation> + </message> +</context> <context> <name>TransactionDesc</name> <message> @@ -1267,6 +1895,10 @@ Address: %4 <translation>Подлежи на промяна до %1</translation> </message> <message> + <source>conflicted</source> + <translation>припокриващ се</translation> + </message> + <message> <source>%1/offline</source> <translation>%1/офлайн</translation> </message> @@ -1323,12 +1955,20 @@ Address: %4 <translation>Дебит</translation> </message> <message> + <source>Total debit</source> + <translation>Общ дълг</translation> + </message> + <message> + <source>Total credit</source> + <translation>Общ дълг</translation> + </message> + <message> <source>Transaction fee</source> <translation>Такса</translation> </message> <message> <source>Net amount</source> - <translation>Сума нето</translation> + <translation>Нетна сума</translation> </message> <message> <source>Message</source> @@ -1347,8 +1987,16 @@ Address: %4 <translation>Търговец</translation> </message> <message> + <source>Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source> + <translation>Генерираните монети трябва да отлежат %1 блока преди да могат да бъдат похарчени. Когато генерираш блока, той се разпространява в мрежата, за да се добави в блок-веригата. Ако не успее да се добави във веригата, неговия статус ще се стане "неприет" и няма да може да се похарчи. Това е възможно да се случи случайно, ако друг възел генерира блок няколко секунди след твоя.</translation> + </message> + <message> + <source>Debug information</source> + <translation>Информация за грешките</translation> + </message> + <message> <source>Transaction</source> - <translation>Трансакция</translation> + <translation>Транзакция</translation> </message> <message> <source>Amount</source> @@ -1375,11 +2023,11 @@ Address: %4 <name>TransactionDescDialog</name> <message> <source>Transaction details</source> - <translation>Трансакция</translation> + <translation>Транзакция</translation> </message> <message> <source>This pane shows a detailed description of the transaction</source> - <translation>Описание на трансакцията</translation> + <translation>Описание на транзакцията</translation> </message> </context> <context> @@ -1393,8 +2041,8 @@ Address: %4 <translation>Тип</translation> </message> <message> - <source>Address</source> - <translation>Адрес</translation> + <source>Immature (%1 confirmations, will be available after %2)</source> + <translation>Неплатим (%1 потвърждения, ще бъде платим след %2)</translation> </message> <message> <source>Open until %1</source> @@ -1413,6 +2061,14 @@ Address: %4 <translation>Генерирана, но отхвърлена от мрежата</translation> </message> <message> + <source>Offline</source> + <translation>Извън линия</translation> + </message> + <message> + <source>Label</source> + <translation>Име</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Непотвърдено</translation> </message> @@ -1426,7 +2082,7 @@ Address: %4 </message> <message> <source>Received with</source> - <translation>Получени с</translation> + <translation>Получени</translation> </message> <message> <source>Received from</source> @@ -1450,19 +2106,15 @@ Address: %4 </message> <message> <source>Transaction status. Hover over this field to show number of confirmations.</source> - <translation>Състояние на трансакцията. Задръжте върху това поле за брой потвърждения.</translation> + <translation>Състояние на транзакцията. Задръжте върху това поле за брой потвърждения.</translation> </message> <message> <source>Date and time that the transaction was received.</source> - <translation>Дата и час на получаване.</translation> + <translation>Дата и час на получаване на транзакцията.</translation> </message> <message> <source>Type of transaction.</source> - <translation>Вид трансакция.</translation> - </message> - <message> - <source>Destination address of transaction.</source> - <translation>Получател на трансакцията.</translation> + <translation>Вид транзакция.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -1549,11 +2201,11 @@ Address: %4 </message> <message> <source>Show transaction details</source> - <translation>Подробности за трансакцията</translation> + <translation>Подробности за транзакцията</translation> </message> <message> <source>Export Transaction History</source> - <translation>Изнасяне историята на трансакциите</translation> + <translation>Изнасяне историята на транзакциите</translation> </message> <message> <source>Exporting Failed</source> @@ -1564,6 +2216,10 @@ Address: %4 <translation>Изнасянето е успешна</translation> </message> <message> + <source>The transaction history was successfully saved to %1.</source> + <translation>Историята с транзакциите беше успешно запазена в %1.</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>CSV файл (*.csv)</translation> </message> @@ -1632,10 +2288,22 @@ Address: %4 <translation>Запазване на портфейла</translation> </message> <message> + <source>Wallet Data (*.dat)</source> + <translation>Информация за портфейла (*.dat)</translation> + </message> + <message> <source>Backup Failed</source> <translation>Неуспешно запазване на портфейла</translation> </message> <message> + <source>There was an error trying to save the wallet data to %1.</source> + <translation>Възникна грешка при запазването на информацията за портфейла в %1.</translation> + </message> + <message> + <source>The wallet data was successfully saved to %1.</source> + <translation>Информацията за портфейла беше успешно запазена в %1.</translation> + </message> + <message> <source>Backup Successful</source> <translation>Успешно запазване на портфейла</translation> </message> @@ -1651,6 +2319,10 @@ Address: %4 <translation>Определете директория за данните</translation> </message> <message> + <source>Connect to a node to retrieve peer addresses, and disconnect</source> + <translation>Свържете се към сървър за да можете да извлечете адресите на пиърите след което се разкачете.</translation> + </message> + <message> <source>Specify your own public address</source> <translation>Въведете Ваш публичен адрес</translation> </message> @@ -1659,18 +2331,38 @@ Address: %4 <translation>Използвайте тестовата мрежа</translation> </message> <message> + <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> + <translation>Приемайте връзки отвън.(по подразбиране:1 в противен случай -proxy или -connect)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Внимание: -paytxfee има голяма стойност! Това е таксата за транзакциите, която ще платите ако направите транзакция.</translation> + <translation>Внимание: -paytxfee е с мното голяма зададена стойност! Това е транзакционната такса, която ще платите ако направите транзакция.</translation> + </message> + <message> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Сложете в бял списък пиъри,свързващи се от дадената интернет маска или айпи адрес.Може да бъде заложено неколкократно.</translation> </message> <message> <source>(default: 1)</source> <translation>(по подразбиране 1)</translation> </message> <message> + <source><category> can be:</source> + <translation><category> може да бъде:</translation> + </message> + <message> <source>Connection options:</source> <translation>Настройки на връзката:</translation> </message> <message> + <source>Do you want to rebuild the block database now?</source> + <translation>Желаете ли да пресъздадете базата данни с блокове сега?</translation> + </message> + <message> + <source>Error initializing block database</source> + <translation>Грешка в пускането на базата данни с блокове</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Грешка: мястото на диска е малко!</translation> </message> @@ -1695,8 +2387,28 @@ Address: %4 <translation>Настройки на портфейла:</translation> </message> <message> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> + <translation>Заложете броя на нишки за генерация на монети ако е включено(-1 = всички ядра, по подразбиране: %d)</translation> + </message> + <message> + <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>Внимание: -maxtxfee има много висока стойност! Толкова високи такси могат да бъдат заплатени на една транзакция.</translation> + </message> + <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Изберете директория при стартиране на програмата.( настройка по подразбиране:0)</translation> + </message> + <message> + <source>Connect through SOCKS5 proxy</source> + <translation>Свързване чрез SOCKS5 прокси</translation> + </message> + <message> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>Всички права запазени (C) 2009-%i Доставчиците на Биткойн</translation> + </message> + <message> <source>Information</source> - <translation>Данни</translation> + <translation>Информация</translation> </message> <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> @@ -1711,16 +2423,28 @@ Address: %4 <translation>Изпрати локализиращата или дебъг информацията към конзолата, вместо файлът debug.log</translation> </message> <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Задаване на език,например "de_DE" (по подразбиране: system locale)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Стартирай минимизирано</translation> + </message> + <message> + <source>This is experimental software.</source> + <translation>Това е експериментален софтуер.</translation> + </message> + <message> <source>Transaction amount too small</source> - <translation>Сумата на трансакцията е твърде малка</translation> + <translation>Сумата на транзакцията е твърде малка</translation> </message> <message> <source>Transaction amounts must be positive</source> - <translation>Сумите на трансакциите трябва да са положителни</translation> + <translation>Сумите на транзакциите трябва да са положителни</translation> </message> <message> <source>Transaction too large</source> - <translation>Трансакцията е твърде голяма</translation> + <translation>Транзакцията е твърде голяма</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -1731,8 +2455,8 @@ Address: %4 <translation>Предупреждение</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Внимание: Използвате остаряла версия, необходимо е обновление!</translation> + <source>on startup</source> + <translation>по време на стартирането</translation> </message> <message> <source>Password for JSON-RPC connections</source> @@ -1744,7 +2468,7 @@ Address: %4 </message> <message> <source>Rescan the block chain for missing wallet transactions</source> - <translation>Повторно сканиране на блок-връзка за липсващи портфейлни трансакции</translation> + <translation>Повторно сканиране на блок-връзка за липсващи портфейлни транзакции</translation> </message> <message> <source>Use OpenSSL (https) for JSON-RPC connections</source> @@ -1756,7 +2480,7 @@ Address: %4 </message> <message> <source>Loading addresses...</source> - <translation>Зареждане на адресите...</translation> + <translation>Зареждане на адреси...</translation> </message> <message> <source>Error loading wallet.dat: Wallet corrupted</source> @@ -1771,6 +2495,18 @@ Address: %4 <translation>Невалиден -proxy address: '%s'</translation> </message> <message> + <source>Specify configuration file (default: %s)</source> + <translation>Назовете конфигурационен файл(по подразбиране %s)</translation> + </message> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Задайте време на изключване при проблеми със свързването в милисекунди(минимум:1, по подразбиране %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Задайте pid файл(по подразбиране: %s)</translation> + </message> + <message> <source>Invalid amount for -paytxfee=<amount>: '%s'</source> <translation>Невалидна сума за -paytxfee=<amount>: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_bs.ts b/src/qt/locale/bitcoin_bs.ts index fc5e6d270e..86526022fe 100644 --- a/src/qt/locale/bitcoin_bs.ts +++ b/src/qt/locale/bitcoin_bs.ts @@ -1,4 +1,4 @@ -<TS language="bs" version="2.1"> +<TS language="bs" version="2.0"> <context> <name>AddressBookPage</name> </context> diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts index fb8e93ea9f..ceb71469cb 100644 --- a/src/qt/locale/bitcoin_ca.ts +++ b/src/qt/locale/bitcoin_ca.ts @@ -1,4 +1,4 @@ -<TS language="ca" version="2.1"> +<TS language="ca" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ <translation>Canvia la contrasenya</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Introduïu tant la contrasenya antiga com la nova del moneder.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Confirma l'encriptació del moneder</translation> </message> @@ -172,6 +168,10 @@ <translation>Esteu segur que voleu encriptar el vostre moneder?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>IMPORTANT: Tota copia de seguretat que hàgiu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder.</translation> </message> @@ -188,8 +188,8 @@ <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin es tancarà ara per acabar el procés d'encriptació. Recordeu que encriptar el moneder no protegeix completament els bitcoins de ser robats per programari maliciós instal·lat a l'ordinador.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Introduïu la contrasenya antiga i la contrasenya nova al moneder.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>Envia monedes a una adreça Bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Modifica les opcions de configuració per bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Realitza una còpia de seguretat del moneder a una altra ubicació</translation> </message> @@ -403,6 +399,10 @@ <translation>&Quant al Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modifica les opcions de configuració del Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Mostra la llista d'adreces d'enviament i etiquetes utilitzades</translation> </message> @@ -431,6 +431,10 @@ <translation>No hi ha cap font de bloc disponible...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>S'han processat %n bloc de l'historial de transacció.</numerusform><numerusform>S'han processat %n blocs de l'historial de transacció.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation> </message> @@ -478,15 +482,41 @@ <source>Up to date</source> <translation>Al dia</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>S'ha processat %n bloc de l'historial de transacció.</numerusform><numerusform>S'han processat %n blocs de l'historial de transacció.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>S'està posant al dia ...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Data: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Import: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tipus: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Etiqueta: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Adreça: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Transacció enviada</translation> </message> @@ -495,14 +525,6 @@ <translation>Transacció entrant</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Data: %1\nImport: %2\n Tipus: %3\n Adreça: %4\n</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>El moneder està <b>encriptat</b> i actualment <b>desbloquejat</b></translation> </message> @@ -693,6 +715,18 @@ Address: %4 <translation>cap</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Aquesta etiqueta es torna en vermell si la transacció és superior a 1000 bytes.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Aquesta etiqueta es torna en vermell si la propietat és inferior que la «mitjana».</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Aquesta etiqueta es torna vermella si el destinatari rep un import inferior de %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Pot variar +/- %1 satoshi(s) per entrada.</translation> </message> @@ -705,10 +739,6 @@ Address: %4 <translation>no</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Aquesta etiqueta es posa de color vermell si la mida de la transacció és més gran de 1000 bytes.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Això comporta una comissió d'almenys %1 per kB.</translation> </message> @@ -721,14 +751,6 @@ Address: %4 <translation>Les transaccions amb una major prioritat són més propenses a ser incloses en un bloc.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Aquesta etiqueta es torna vermella si la prioritat és menor que «mitjana».</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Aquesta etiqueta es torna vermella si qualsevol destinatari rep un import inferior a %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(sense etiqueta)</translation> </message> @@ -849,30 +871,6 @@ Address: %4 <source>command-line options</source> <translation>Opcions de la línia d'ordres</translation> </message> - <message> - <source>UI options</source> - <translation>Opcions de IU</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Inicia minimitzat</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostra la finestra de benvinguda a l'inici (per defecte: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Tria el directori de dades a l'inici (per defecte: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -955,14 +953,6 @@ Address: %4 <translation>&Principal</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Inicia automàticament el Bitcoin després de l'inici de sessió del sistema.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Inicia el Bitcoin a l'inici de sessió del sistema.</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Mida de la memòria cau de la base de &dades</translation> </message> @@ -987,6 +977,14 @@ Address: %4 <translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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ú. </translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>La interfície d'usuari pot definir-se des d'aquí. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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 |.</translation> </message> @@ -1011,6 +1009,14 @@ Address: %4 <translation>&Xarxa</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Inicia el Bitcoin Core en inciar el sistema</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = deixa tants nuclis lliures)</translation> </message> @@ -1075,10 +1081,6 @@ Address: %4 <translation>&Minimitza a la barra d'aplicacions en comptes de la barra de tasques</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimitza en comptes de sortir de la aplicació al tancar la finestra. Quan aquesta opció està activa, la aplicació només es tancarà al seleccionar Sortir al menú.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimitza en tancar</translation> </message> @@ -1091,10 +1093,6 @@ Address: %4 <translation>&Llengua de la interfície d'usuari:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Aquí podeu definir la llengua de l'aplicació. Aquesta configuració tindrà efecte una vegada es reiniciï Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Unitats per mostrar els imports en:</translation> </message> @@ -1131,8 +1129,8 @@ Address: %4 <translation>Cal reiniciar el client per activar els canvis.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>S'aturarà el client, voleu procedir?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>S'aturarà el client. Voleu procedir?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1217,10 +1215,6 @@ Address: %4 <source>Current total balance in watch-only addresses</source> <translation>Balanç total actual en adreces de només lectura</translation> </message> - <message> - <source>out of sync</source> - <translation>Fora de sincronia</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1241,10 +1235,6 @@ Address: %4 <translation>La xarxa de la sol·licitud de pagament no coincideix amb la xarxa del client.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>La sol·licitud de pagament ha caducat.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>La sol·licitud de pagament no està inicialitzada.</translation> </message> @@ -1277,10 +1267,18 @@ Address: %4 <translation>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.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>La sol·licitud de pagament ha vençut.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Sol·licitud de pagament no vàlida.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Reemborsament de %1</translation> </message> @@ -1320,8 +1318,8 @@ Address: %4 <translation>Agent d'usuari</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Adreça / nom de l'ordinador</translation> + <source>Node/Service</source> + <translation>Node/Servei</translation> </message> <message> <source>Ping Time</source> @@ -1355,14 +1353,6 @@ Address: %4 <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>XARXA</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>DESCONEGUT</translation> - </message> - <message> <source>None</source> <translation>Cap</translation> </message> @@ -1453,6 +1443,10 @@ Address: %4 <translation>Nombre de blocs actuals</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>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.</translation> + </message> + <message> <source>Received</source> <translation>Rebut</translation> </message> @@ -1521,6 +1515,10 @@ Address: %4 <translation>Temps de ping</translation> </message> <message> + <source>Time Offset</source> + <translation>Diferència horària</translation> + </message> + <message> <source>Last block time</source> <translation>Últim temps de bloc</translation> </message> @@ -1561,16 +1559,12 @@ Address: %4 <translation>Fitxer de registre de depuració</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Obre el fitxer de registre de depuració de Bitcoin del directori de dades actual. Això pot trigar uns quants segons per a fitxers de registre grans.</translation> - </message> - <message> <source>Clear console</source> <translation>Neteja la consola</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Us donem la benvinguda a la consola RPC de Bitcoin</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Us donem la benviguda a la consola RPC del Bitcoin Core.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1861,14 +1855,6 @@ Address: %4 <translation>redueix els paràmetres de comissió</translation> </message> <message> - <source>Minimize</source> - <translation>Minimitza</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation> - </message> - <message> <source>per kilobyte</source> <translation>per kilobyte</translation> </message> @@ -1877,6 +1863,10 @@ Address: %4 <translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «total com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation> </message> <message> + <source>Hide</source> + <translation>Amaga</translation> + </message> + <message> <source>total at least</source> <translation>total com a mínim</translation> </message> @@ -1997,10 +1987,6 @@ Address: %4 <translation>o</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>L'adreça de destinatari no és vàlida, si us plau comprovi-la.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>L'import a pagar ha de ser major que 0.</translation> </message> @@ -2013,10 +1999,6 @@ Address: %4 <translation>El total excedeix el teu balanç quan s'afegeix la comissió a la transacció %1.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>S'ha trobat una adreça duplicada, tan sols es pot enviar a cada adreça un cop per ordre de enviament.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Ha fallat la creació de la transacció!</translation> </message> @@ -2025,16 +2007,28 @@ Address: %4 <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> - <translation>Una comissió superior a %1 es considera una comissió excessiva.</translation> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Una comissió superior a %1 es considera una comissió absurdament alta.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>La sol·licitud de pagament ha vençut.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation> </message> <message> <source>Pay only the minimum fee of %1</source> <translation>Paga només la comissió mínima de %1</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Estimat per a començar la confirmació en %1 bloc(s).</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2108,12 +2102,24 @@ Address: %4 <translation>Elimina aquesta entrada</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>La comissió es deduirà de l'import que s'enviarà. El destinatari rebrà menys bitcoins que les que introduïu al camp d'import. Si se seleccionen múltiples destinataris, la comissió es dividirà per igual.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>S&ubstreu la comissió de l'import</translation> + </message> + <message> <source>Message:</source> <translation>Missatge:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Aquesta és una sol·licitud de pagament verificada.</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Aquesta és una sol·licitud de pagament no autenticada.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Aquesta és una sol·licitud de pagament autenticada.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2124,10 +2130,6 @@ Address: %4 <translation>Un missatge que s'ha adjuntat al bitcoin: URI que s'emmagatzemarà amb la transacció per a la vostra referència. Nota: el missatge no s'enviarà a través de la xarxa Bitcoin.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Aquesta és una sol·licitud de pagament no verificada.</translation> - </message> - <message> <source>Pay To:</source> <translation>Paga a:</translation> </message> @@ -2158,8 +2160,8 @@ Address: %4 <translation>&Signa el missatge</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Podeu signar missatges amb la vostra adreça per provar que són vostres. Aneu amb compte no signar qualsevol cosa, ja que els atacs de pesca electrònica (phishing) poden provar de confondre-us perquè els signeu amb la vostra identitat. Només signeu als documents completament detallats amb què hi esteu d'acord.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Podeu signar missatges/acords amb les vostres adreces per provar que rebeu les bitcoins que s'hi envien. Aneu amb compte no signar res que sigui vague o aleatori, perquè en alguns atacs de suplantació es pot provar que hi signeu la vostra identitat. Només signeu aquelles declaracions completament detallades en què hi esteu d'acord. </translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2214,8 +2216,8 @@ Address: %4 <translation>&Verifica el missatge</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Introdueixi l'adreça signant, missatge (assegura't que copies salts de línia, espais, tabuladors, etc excactament tot el text) i la signatura a sota per verificar el missatge. Per evitar ser enganyat per un atac home-entre-mig, vés amb compte de no llegir més en la signatura del que hi ha al missatge signat mateix.</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Introduïu l'adreça del receptor, el missatge (assegureu-vos de copiar els salts de línia, espais, tabuladors, etc. exactament) i signatura de sota per verificar el missatge. Tingueu cura de no llegir més en la signatura del que està al missatge signat, per evitar ser enganyat per un atac d'home-en-el-mig. Tingueu en compte que això només demostra que la part que signa rep amb l'adreça, i no es pot provar l'enviament de qualsevol transacció!</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2481,10 +2483,6 @@ Address: %4 <translation>Tipus</translation> </message> <message> - <source>Address</source> - <translation>Adreça</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Immadur (%1 confirmacions, serà disponible després de %2)</translation> </message> @@ -2513,6 +2511,10 @@ Address: %4 <translation>Fora de línia</translation> </message> <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Sense confirmar</translation> </message> @@ -2569,8 +2571,8 @@ Address: %4 <translation>Si està implicada o no una adreça només de lectura en la transacció.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Adreça del destinatari de la transacció.</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Intenció/propòsit de la transacció definida per l'usuari.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2823,16 +2825,16 @@ Address: %4 <translation>Distribuït sota llicència de programari MIT. Vegeu el fitxer acompanyant COPYING o <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Entra en el mode de proves de regressió, que utilitza una cadena especial en què els blocs poden resoldre's al moment.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Executa una ordre quan una transacció del moneder canviï (%s en cmd es canvia per TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>En aquest mode -genproclimit controla quants blocs es generen immediatament.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Redueix els requeriments d'emmagatzemament podant (suprimint) els blocs antics. Aquest mode inhabilita l'ús de moneders i és incompatible amb -tindex. Avís: Revertir aquesta configuració comporta tornar a baixar la cadena de blocs sencera. (per defecte: 0 = inhabilita la poda de blocs, >%u = mida objectiu en MiB per utilitzar els fitxers de blocs)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2847,6 +2849,14 @@ Address: %4 <translation>No es pot enllaçar %s a aquest ordinador. El Bitcoin Core probablement ja estigui executant-s'hi.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Avís: el -paytxfee és molt elevat! Aquesta és la comissió de transacció que pagareu si envieu una transacció.</translation> </message> @@ -2903,10 +2913,6 @@ Address: %4 <translation>Opcions de depuració/proves:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Descobreix la pròpia adreça IP (per defecte: 1 quan escoltant i no -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>No carreguis el moneder i inhabilita les crides RPC del moneder</translation> </message> @@ -2967,8 +2973,12 @@ Address: %4 <translation>Només connecta als nodes de la xarxa <net> (ipv4, ipv6 o onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers actuals blk000??.dat</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>La poda no es pot configurar amb un valor negatiu.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>El mode de poda és incompatible amb -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2983,10 +2993,6 @@ Address: %4 <translation>Especifica un fitxer de moneder (dins del directori de dades)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Això es així per a eines de proves de regressió per al desenvolupament d'aplicacions.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Utilitza UPnP per a mapejar el port d'escolta (per defecte: %u)</translation> </message> @@ -3007,6 +3013,10 @@ Address: %4 <translation>Opcions de moneder:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Avís: aquesta versió és obsoleta; cal actualitzar-la!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation> </message> @@ -3031,14 +3041,14 @@ Address: %4 <translation>No es pot obtenir un bloqueig del directori de dades %s. El Bitcoin Core probablement ja s'estigui executant.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Limita contínuament la freqüència de les transaccions gratuïtes a <n>*1000 bytes per minut (per defecte: %u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>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)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Descobreix l'adreça IP pròpia (per defecte: 1 quan s'escolta i no -externalip o -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation> </message> @@ -3055,10 +3065,6 @@ Address: %4 <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la transmissió (per defecte: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la creació de la transacció (per defecte: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencin a confirmar-se en una mitja de n blocs (per defecte: %u)</translation> </message> @@ -3071,16 +3077,16 @@ Address: %4 <translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meves (per defecte: %u)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>Comissions totals màximes que s'utilitzaran en una transacció d'un únic moneder. Si es defineix un valor massa baix les transaccions més grans poden interrompre's (per defecte: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Poda configurada per sota el mínim de %d MB. Feu servir un nombre superior.</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>Es requereix una prioritat alta per retransmetre transaccions gratuïtes o de baixa comissió (per defecte:%u)</translation> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Genera a l'atzar credencials per a cada connexió proxy. Això habilita l'aïllament del flux de Tor (per defecte: %u)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3091,6 +3097,10 @@ Address: %4 <translation>Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>L'import de la transacció és massa petit per enviar-la després que se'n dedueixi la comissió</translation> + </message> + <message> <source>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.</source> <translation>Aquest producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit <https://www.openssl.org/> i programari criptogràfic escrit per Eric Young i programari UPnP escrit per Thomas Bernard.</translation> </message> @@ -3130,14 +3140,34 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Els iguals en la llista blanca no poden ser bandejats per DoS i es transmetran sempre llurs transaccions, fins i tot si ja són a la mempool. Això és útil, p. ex., per a una passarel·la</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Cal que torneu a construir la base de dades fent servir -reindex per tornar al mode no podat. Això tornarà a baixar la cadena de blocs sencera</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(per defecte: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Accepta sol·licituds REST públiques (per defecte: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>S'està activant la millor cadena...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>No es pot executar amb un moneder en mode poda.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Tria el directori de dades a l'inici (per defecte: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Connecta a través del proxy SOCKS5</translation> </message> @@ -3218,12 +3248,12 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Descarta a l'atzar 1 de cada <n> missatges de la xarxa</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Introdueix incertesa en 1 de cada <n> missatges de la xarxa</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Rep i mostra avisos de la xarxa P2P (per defecte: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3234,10 +3264,22 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Envia les transaccions com a transaccions de comissió zero sempre que sigui possible (per defecte: %u) </translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Mostra totes les opcions de depuració (ús: --help --help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Mostra la finestra de benvinguda a l'inici (per defecte: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Redueix el fitxer debug.log durant l'inici del client (per defecte: 1 quan no -debug)</translation> </message> @@ -3246,6 +3288,14 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Ha fallat la signatura de la transacció</translation> </message> <message> + <source>Start minimized</source> + <translation>Inicia minimitzat</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Això és programari experimental.</translation> </message> @@ -3266,6 +3316,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>La transacció és massa gran</translation> </message> <message> + <source>UI Options:</source> + <translation>Opcions d'interfície:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>No s'ha pogut vincular a %s en aquest ordinador (la vinculació ha retornat l'error %s)</translation> </message> @@ -3286,10 +3340,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Avís</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Avís: aquesta versió està obsoleta. És necessari actualitzar-la!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Avís: s'ha ignorat l'argument no acceptat de -benchmark. Feu servir -debug=bench.</translation> </message> @@ -3350,18 +3400,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>(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)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Buida l'activitat de la base de dades de la memòria disponible al registre del disc cada <n> megabytes (per defecte: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Com d'exhaustiva és la verificació de blocs del -checkblocks (0-4, per defecte: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Enregistreu la prioritat de la transacció i la comissió per kB en minar blocs (per defecte: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Manté un índex complet de transaccions, utilitzat per la crida rpc getrawtransaction (per defecte: %u)</translation> </message> @@ -3390,18 +3432,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Inhabilita el mode segur, sobreescriu un esdeveniment de mode segur real (per defecte: %u) </translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Error en carregar wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Força el mode segur (per defecte: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Genera monedes (per defecte: %u)</translation> </message> @@ -3418,10 +3452,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Adreça -proxy invalida: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Limita la mida de la cau de signatura a <n> entrades (per defecte: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Escolta les connexions JSON-RPC en <port> (per defecte: %u o testnet: %u)</translation> </message> @@ -3434,6 +3464,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Manté com a màxim <n> connexions a iguals (per defecte: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Fes que el moneder faci difusió de les transaccions</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Memòria intermèdia màxima de recepció per connexió, <n>*1000 bytes (per defecte: %u)</translation> </message> @@ -3442,10 +3476,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Memòria intermèdia màxima d'enviament per connexió, <n>*1000 bytes (per defecte: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Només accepta els punts de control integrats que coincideixen amb la cadena de blocs (per defecte: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Posa davant de la sortida de depuració una marca horària (per defecte: %u)</translation> </message> @@ -3458,10 +3488,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Retransmet multisig no P2SH (per defecte: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Executa un fil per buidar el moneder periòdicament (per defecte: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Fitxer de certificat del servidor (per defecte: %s)</translation> </message> @@ -3482,10 +3508,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Defineix el nombre de fils a crides de servei RPC (per defecte: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Defineix el senyalador DB_PRIVATE en l'entorn db del moneder (per defecte: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Especifica el fitxer de configuració (per defecte: %s)</translation> </message> @@ -3502,10 +3524,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Gasta el canvi no confirmat en enviar les transaccions (per defecte: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Atura l'execució després d'importar blocs del disc (per defecte: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Llindar per a desconnectar els iguals de comportament qüestionable (per defecte: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts index 349fc6b42e..b77845cfb2 100644 --- a/src/qt/locale/bitcoin_ca@valencia.ts +++ b/src/qt/locale/bitcoin_ca@valencia.ts @@ -1,7 +1,11 @@ -<TS language="ca@valencia" version="2.1"> +<TS language="ca@valencia" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Feu clic dret per a editar l'adreça o l'etiqueta</translation> + </message> + <message> <source>Create a new address</source> <translation>Crea una nova adreça</translation> </message> @@ -152,10 +156,6 @@ <translation>Canvia la contrasenya</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Introduïu tant la contrasenya antiga com la nova del moneder.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Confirma l'encriptació del moneder</translation> </message> @@ -168,6 +168,10 @@ <translation>Esteu segur que voleu encriptar el vostre moneder?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>IMPORTANT: Tota copia de seguretat que hàgeu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder.</translation> </message> @@ -184,8 +188,8 @@ <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin es tancarà ara per acabar el procés d'encriptació. Recordeu que encriptar el moneder no protegeix completament els bitcoins de ser robats per programari maliciós instal·lat a l'ordinador.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Introduïu la contrasenya antiga i la contrasenya nova al moneder.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -307,10 +311,6 @@ <translation>Envia monedes a una adreça Bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Modifica les opcions de configuració per bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Realitza una còpia de seguretat del moneder a una altra ubicació</translation> </message> @@ -399,6 +399,10 @@ <translation>&Quant al Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modifica les opcions de configuració del Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Mostra la llista d'adreces d'enviament i etiquetes utilitzades</translation> </message> @@ -418,14 +422,34 @@ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> <translation>Mostra el missatge d'ajuda del Bitcoin Core per obtindre una llista amb les possibles opcions de línia d'ordes de Bitcoin</translation> </message> + <message numerus="yes"> + <source>%n active connection(s) to Bitcoin network</source> + <translation><numerusform>%n connexió activa a la xarxa Bitcoin</numerusform><numerusform>%n connexions actives a la xarxa Bitcoin</numerusform></translation> + </message> <message> <source>No block source available...</source> <translation>No hi ha cap font de bloc disponible...</translation> </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n dia</numerusform><numerusform>%n dies</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n setmana</numerusform><numerusform>%n setmanes</numerusform></translation> + </message> <message> <source>%1 and %2</source> <translation>%1 i %2</translation> </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n any</numerusform><numerusform>%n anys</numerusform></translation> + </message> <message> <source>%1 behind</source> <translation>%1 darrere</translation> @@ -459,6 +483,36 @@ <translation>S'està posant al dia ...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Data: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Import: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tipus: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Etiqueta: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Adreça: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Transacció enviada</translation> </message> @@ -467,14 +521,6 @@ <translation>Transacció entrant</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Data: %1\nImport: %2\n Tipus: %3\n Adreça: %4\n</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>El moneder està <b>encriptat</b> i actualment <b>desbloquejat</b></translation> </message> @@ -493,6 +539,10 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>Selecció de moneda</translation> + </message> + <message> <source>Quantity:</source> <translation>Quantitat:</translation> </message> @@ -510,7 +560,7 @@ Address: %4 </message> <message> <source>Fee:</source> - <translation>Quota:</translation> + <translation>Comissió</translation> </message> <message> <source>Dust:</source> @@ -518,7 +568,7 @@ Address: %4 </message> <message> <source>After Fee:</source> - <translation>Quota posterior:</translation> + <translation>Comissió posterior:</translation> </message> <message> <source>Change:</source> @@ -538,7 +588,15 @@ Address: %4 </message> <message> <source>Amount</source> - <translation>Quantitat</translation> + <translation>Import</translation> + </message> + <message> + <source>Received with label</source> + <translation>Rebut amb l'etiqueta</translation> + </message> + <message> + <source>Received with address</source> + <translation>Rebut amb l'adreça</translation> </message> <message> <source>Date</source> @@ -653,6 +711,18 @@ Address: %4 <translation>cap</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Esta etiqueta es torna en roig si la transacció és superior a 1000 bytes.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Esta etiqueta es torna en roig si la propietat és inferior que la «mitjana».</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Esta etiqueta es torna roja si el destinatari rep un import inferior de %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Pot variar +/- %1 satoshi(s) per entrada.</translation> </message> @@ -665,12 +735,8 @@ Address: %4 <translation>no</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Esta etiqueta es posa de color roig si la mida de la transacció és més gran de 1000 bytes.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> - <translation>Això comporta una comissi d'almenys %1 per kB.</translation> + <translation>Això comporta una comissió d'almenys %1 per kB.</translation> </message> <message> <source>Can vary +/- 1 byte per input.</source> @@ -681,14 +747,6 @@ Address: %4 <translation>Les transaccions amb una major prioritat són més propenses a ser incloses en un bloc.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Esta etiqueta es torna roja si la prioritat és menor que «mitjana».</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Esta etiqueta es torna roja si qualsevol destinatari rep un import inferior a %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(sense etiqueta)</translation> </message> @@ -705,7 +763,7 @@ Address: %4 <name>EditAddressDialog</name> <message> <source>Edit Address</source> - <translation>Editar Adreça</translation> + <translation>Edita l'adreça</translation> </message> <message> <source>&Label</source> @@ -809,30 +867,6 @@ Address: %4 <source>command-line options</source> <translation>Opcions de la línia d'ordes</translation> </message> - <message> - <source>UI options</source> - <translation>Opcions d'IU</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Defineix un idioma, per exemple "de_DE" (per defecte: preferències locals de sistema)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Inicia minimitzat</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostra la finestra de benvinguda a l'inici (per defecte: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Tria el directori de dades a l'inici (per defecte: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -872,7 +906,15 @@ Address: %4 <source>Error</source> <translation>Error</translation> </message> - </context> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB d'espai lliure disponible</numerusform><numerusform>%n GB d'espai lliure disponible</numerusform></translation> + </message> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(de %n GB necessari)</numerusform><numerusform>(de %n GB necessaris)</numerusform></translation> + </message> +</context> <context> <name>OpenURIDialog</name> <message> @@ -907,14 +949,6 @@ Address: %4 <translation>&Principal</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Inicia automàticament el Bitcoin després de l'inici de sessió del sistema.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Inicia el Bitcoin a l'inici de sessió del sistema.</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Mida de la memòria cau de la base de &dades</translation> </message> @@ -939,6 +973,14 @@ Address: %4 <translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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ú. </translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>La interfície d'usuari pot definir-se des d'ací. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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 |.</translation> </message> @@ -963,6 +1005,14 @@ Address: %4 <translation>&Xarxa</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Inicia el Bitcoin Core en inciar el sistema</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = deixa tants nuclis lliures)</translation> </message> @@ -995,6 +1045,14 @@ Address: %4 <translation>Port obert amb &UPnP</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Connecta a la xarxa Bitcoin a través d'un proxy SOCKS5.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Connecta a través d'un proxy SOCKS5 (proxy per defecte):</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>&IP del proxy:</translation> </message> @@ -1019,10 +1077,6 @@ Address: %4 <translation>&Minimitza a la barra d'aplicacions en comptes de la barra de tasques</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimitza en comptes d'eixir de la aplicació al tancar la finestra. Quan esta opció està activa, la aplicació només es tancarà al seleccionar Eixir al menú.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimitza en tancar</translation> </message> @@ -1035,10 +1089,6 @@ Address: %4 <translation>&Llengua de la interfície d'usuari:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Ací podeu definir la llengua de l'aplicació. Esta configuració tindrà efecte una vegada es reinicie Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Unitats per mostrar els imports en:</translation> </message> @@ -1075,8 +1125,8 @@ Address: %4 <translation>Cal reiniciar el client per activar els canvis.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Es pararà el client, voleu procedir?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Es pararà el client. Voleu procedir?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1126,6 +1176,10 @@ Address: %4 <translation>Balanç minat que encara no ha madurat</translation> </message> <message> + <source>Balances</source> + <translation>Balances</translation> + </message> + <message> <source>Total:</source> <translation>Total:</translation> </message> @@ -1138,6 +1192,14 @@ Address: %4 <translation>El vostre balanç actual en adreces de només lectura</translation> </message> <message> + <source>Spendable:</source> + <translation>Que es pot gastar:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Transaccions recents</translation> + </message> + <message> <source>Unconfirmed transactions to watch-only addresses</source> <translation>Transaccions sense confirmar a adreces de només lectura</translation> </message> @@ -1149,10 +1211,6 @@ Address: %4 <source>Current total balance in watch-only addresses</source> <translation>Balanç total actual en adreces de només lectura</translation> </message> - <message> - <source>out of sync</source> - <translation>Fora de sincronia</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1173,10 +1231,6 @@ Address: %4 <translation>La xarxa de la sol·licitud de pagament no coincideix amb la xarxa del client.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>La sol·licitud de pagament ha caducat.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>La sol·licitud de pagament no està inicialitzada.</translation> </message> @@ -1209,14 +1263,30 @@ Address: %4 <translation>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.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>La sol·licitud de pagament ha vençut.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Sol·licitud de pagament no vàlida.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Reemborsament de %1</translation> </message> <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>La sol·licitud de pagament %1 és massa gran (%2 bytes, permés %3 bytes).</translation> + </message> + <message> + <source>Payment request DoS protection</source> + <translation>Protecció de DoS per a la sol·licitud de pagament</translation> + </message> + <message> <source>Error communicating with %1: %2</source> <translation>Error en comunicar amb %1: %2</translation> </message> @@ -1244,8 +1314,8 @@ Address: %4 <translation>Agent d'usuari</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Adreça / nom de l'ordinador</translation> + <source>Node/Service</source> + <translation>Node/Servei</translation> </message> <message> <source>Ping Time</source> @@ -1256,7 +1326,7 @@ Address: %4 <name>QObject</name> <message> <source>Amount</source> - <translation>Quantitat</translation> + <translation>Import</translation> </message> <message> <source>Enter a Bitcoin address (e.g. %1)</source> @@ -1279,14 +1349,6 @@ Address: %4 <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>XARXA</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>DESCONEGUT</translation> - </message> - <message> <source>None</source> <translation>Cap</translation> </message> @@ -1377,6 +1439,10 @@ Address: %4 <translation>Nombre de blocs actuals</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>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.</translation> + </message> + <message> <source>Received</source> <translation>Rebut</translation> </message> @@ -1445,6 +1511,10 @@ Address: %4 <translation>Temps de ping</translation> </message> <message> + <source>Time Offset</source> + <translation>Diferència horària</translation> + </message> + <message> <source>Last block time</source> <translation>Últim temps de bloc</translation> </message> @@ -1485,16 +1555,12 @@ Address: %4 <translation>Fitxer de registre de depuració</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Obri el fitxer de registre de depuració de Bitcoin del directori de dades actual. Això pot trigar uns quants segons per a fitxers de registre grans.</translation> - </message> - <message> <source>Clear console</source> <translation>Neteja la consola</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Vos donem la benvinguda a la consola RPC de Bitcoin</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Vos donem la benviguda a la consola RPC del Bitcoin Core.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1758,7 +1824,7 @@ Address: %4 </message> <message> <source>After Fee:</source> - <translation>Quota posterior:</translation> + <translation>Comissió posterior:</translation> </message> <message> <source>Change:</source> @@ -1773,6 +1839,74 @@ Address: %4 <translation>Personalitza l'adreça de canvi</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Comissió de transacció</translation> + </message> + <message> + <source>Choose...</source> + <translation>Tria...</translation> + </message> + <message> + <source>collapse fee-settings</source> + <translation>redueix els paràmetres de comissió</translation> + </message> + <message> + <source>per kilobyte</source> + <translation>per kilobyte</translation> + </message> + <message> + <source>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.</source> + <translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «total com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation> + </message> + <message> + <source>Hide</source> + <translation>Amaga</translation> + </message> + <message> + <source>total at least</source> + <translation>total com a mínim</translation> + </message> + <message> + <source>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.</source> + <translation>No hi ha cap problema en pagar només la comissió mínima sempre que hi haja menys volum de transacció que espai en els blocs. Però tingueu present que això pot acabar en una transacció que mai es confirme una vegada hi haja més demanda de transaccions de bitcoins que la xarxa puga processar.</translation> + </message> + <message> + <source>(read the tooltip)</source> + <translation>(llegiu l'indicador de funció)</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Recomanada:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Personalitzada:</translation> + </message> + <message> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> + <translation>(No s'ha inicialitzat encara la comissió intel·ligent. Normalment pren uns pocs blocs...)</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Temps de confirmació:</translation> + </message> + <message> + <source>normal</source> + <translation>normal</translation> + </message> + <message> + <source>fast</source> + <translation>ràpid</translation> + </message> + <message> + <source>Send as zero-fee transaction if possible</source> + <translation>Envia com a transacció de comissió zero si és possible</translation> + </message> + <message> + <source>(confirmation may take longer)</source> + <translation>(la confirmació pot trigar més temps)</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Envia a múltiples destinataris al mateix temps</translation> </message> @@ -1822,7 +1956,7 @@ Address: %4 </message> <message> <source>Copy fee</source> - <translation>Copia la comissi</translation> + <translation>Copia la comissió</translation> </message> <message> <source>Copy after fee</source> @@ -1849,10 +1983,6 @@ Address: %4 <translation>o</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>L'adreça de destinatari no és vàlida, per favor comprovi-la.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>L'import a pagar ha de ser major que 0.</translation> </message> @@ -1862,11 +1992,7 @@ Address: %4 </message> <message> <source>The total exceeds your balance when the %1 transaction fee is included.</source> - <translation>El total excedeix el teu balanç quan s'afig la comisió a la transacció %1.</translation> - </message> - <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>S'ha trobat una adreça duplicada, tan sols es pot enviar a cada adreça un cop per orde d'enviament.</translation> + <translation>El total excedeix el teu balanç quan s'afig la comissió a la transacció %1.</translation> </message> <message> <source>Transaction creation failed!</source> @@ -1877,6 +2003,30 @@ Address: %4 <translation>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.</translation> </message> <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Una comissió superior a %1 es considera una comissió absurdament alta.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>La sol·licitud de pagament ha vençut.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation> + </message> + <message> + <source>Pay only the minimum fee of %1</source> + <translation>Paga només la comissió mínima de %1</translation> + </message> + <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Avís: adreça Bitcoin no vàlida</translation> </message> @@ -1948,12 +2098,24 @@ Address: %4 <translation>Elimina esta entrada</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>La comissió es deduirà de l'import que s'enviarà. El destinatari rebrà menys bitcoins que les que introduïu al camp d'import. Si se seleccionen múltiples destinataris, la comissió es dividirà per igual.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>S&ubstreu la comissió de l'import</translation> + </message> + <message> <source>Message:</source> <translation>Missatge:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Esta és una sol·licitud de pagament verificada.</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Esta és una sol·licitud de pagament no autenticada.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Esta és una sol·licitud de pagament autenticada.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -1964,10 +2126,6 @@ Address: %4 <translation>Un missatge que s'ha adjuntat al bitcoin: URI que s'emmagatzemarà amb la transacció per a la vostra referència. Nota: el missatge no s'enviarà a través de la xarxa Bitcoin.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Esta és una sol·licitud de pagament no verificada.</translation> - </message> - <message> <source>Pay To:</source> <translation>Paga a:</translation> </message> @@ -1998,8 +2156,8 @@ Address: %4 <translation>&Signa el missatge</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Podeu signar missatges amb la vostra adreça per provar que són vostres. Aneu amb compte no signar qualsevol cosa, ja que els atacs de pesca electrònica (phishing) poden provar de confondre-vos perquè els signeu amb la vostra identitat. Només signeu als documents completament detallats amb què hi esteu d'acord.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Podeu signar missatges/acords amb les vostres adreces per provar que rebeu les bitcoins que s'hi envien. Aneu amb compte no signar res que siga vague o aleatori, perquè en alguns atacs de suplantació es pot provar que hi signeu la vostra identitat. Només signeu aquelles declaracions completament detallades en què hi esteu d'acord. </translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2054,8 +2212,8 @@ Address: %4 <translation>&Verifica el missatge</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Introduïsca l'adreça signant, missatge (assegura't que copies salts de línia, espais, tabuladors, etc excactament tot el text) i la signatura a sota per verificar el missatge. Per evitar ser enganyat per un atac home-entre-mig, vés amb compte de no llegir més en la signatura del que hi ha al missatge signat mateix.</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Introduïu l'adreça del receptor, el missatge (assegureu-vos de copiar els salts de línia, espais, tabuladors, etc. exactament) i signatura de sota per verificar el missatge. Tingueu cura de no llegir més en la signatura del que està al missatge signat, per evitar ser enganyat per un atac d'home-en-el-mig. Tingueu en compte que això només demostra que la part que signa rep amb l'adreça, i no es pot provar l'enviament de qualsevol transacció!</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2174,6 +2332,10 @@ Address: %4 <source>Status</source> <translation>Estat</translation> </message> + <message numerus="yes"> + <source>, broadcast through %n node(s)</source> + <translation><numerusform>, difusió a través de %n node</numerusform><numerusform>, difusió a través de %n nodes</numerusform></translation> + </message> <message> <source>Date</source> <translation>Data</translation> @@ -2210,6 +2372,10 @@ Address: %4 <source>Credit</source> <translation>Crèdit</translation> </message> + <message numerus="yes"> + <source>matures in %n more block(s)</source> + <translation><numerusform>madura en %n bloc més</numerusform><numerusform>madura en %n blocs més</numerusform></translation> + </message> <message> <source>not accepted</source> <translation>no acceptat</translation> @@ -2268,7 +2434,7 @@ Address: %4 </message> <message> <source>Amount</source> - <translation>Quantitat</translation> + <translation>Import</translation> </message> <message> <source>true</source> @@ -2282,6 +2448,10 @@ Address: %4 <source>, has not been successfully broadcast yet</source> <translation>, encara no ha estat emés correctement</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Obri per %n bloc més</numerusform><numerusform>Obri per %n blocs més</numerusform></translation> + </message> <message> <source>unknown</source> <translation>desconegut</translation> @@ -2309,13 +2479,13 @@ Address: %4 <translation>Tipus</translation> </message> <message> - <source>Address</source> - <translation>Adreça</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Immadur (%1 confirmacions, serà disponible després de %2)</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Obri per %n bloc més</numerusform><numerusform>Obri per %n blocs més</numerusform></translation> + </message> <message> <source>Open until %1</source> <translation>Obert fins %1</translation> @@ -2337,6 +2507,10 @@ Address: %4 <translation>Fora de línia</translation> </message> <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Sense confirmar</translation> </message> @@ -2389,8 +2563,12 @@ Address: %4 <translation>Tipus de transacció.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Adreça del destinatari de la transacció.</translation> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Si està implicada o no una adreça només de lectura en la transacció.</translation> + </message> + <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Intenció/propòsit de la transacció definida per l'usuari.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2484,6 +2662,10 @@ Address: %4 <translation>Exporta l'historial de transacció</translation> </message> <message> + <source>Watch-only</source> + <translation>Només de lectura</translation> + </message> + <message> <source>Exporting Failed</source> <translation>L'exportació ha fallat</translation> </message> @@ -2635,16 +2817,20 @@ Address: %4 <translation>Elimina totes les transaccions del moneder i només recupera aquelles de la cadena de blocs a través de -rescan a l'inici</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Entra en el mode de proves de regressió, que utilitza una cadena especial en què els blocs poden resoldre's al moment.</translation> + <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> + <translation>Distribuït sota llicència de programari MIT. Vegeu el fitxer acompanyant COPYING o <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Executa una orde quan una transacció del moneder canvie (%s en cmd es canvia per TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>En este mode -genproclimit controla quants blocs es generen immediatament.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Redueix els requeriments d'emmagatzemament podant (suprimint) els blocs antics. Este mode inhabilita l'ús de moneders i és incompatible amb -tindex. Avís: Revertir esta configuració comporta tornar a baixar la cadena de blocs sencera. (per defecte: 0 = inhabilita la poda de blocs, >%u = mida objectiu en MiB per utilitzar els fitxers de blocs)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2659,6 +2845,14 @@ Address: %4 <translation>No es pot enllaçar %s a este ordinador. El Bitcoin Core probablement ja estiga executant-s'hi.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Avís: el -paytxfee és molt elevat! Esta és la comissió de transacció que pagareu si envieu una transacció.</translation> </message> @@ -2679,6 +2873,10 @@ Address: %4 <translation>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.</translation> </message> <message> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>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.</translation> + </message> + <message> <source>(default: 1)</source> <translation>(per defecte: 1)</translation> </message> @@ -2711,10 +2909,6 @@ Address: %4 <translation>Opcions de depuració/proves:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Descobreix la pròpia adreça IP (per defecte: 1 quan escoltant i no -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>No carreguis el moneder i inhabilita les crides RPC del moneder</translation> </message> @@ -2739,6 +2933,10 @@ Address: %4 <translation>Error en obrir la base de dades de blocs</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Error: s'ha produït un error intern fatal. Consulteu debug.log per a més detalls</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Error: Espai al disc baix!</translation> </message> @@ -2767,8 +2965,16 @@ Address: %4 <translation>No hi ha suficient descriptors de fitxers disponibles.</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers actuals blk000??.dat</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>Només connecta als nodes de la xarxa <net> (ipv4, ipv6 o onion)</translation> + </message> + <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>La poda no es pot configurar amb un valor negatiu.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>El mode de poda és incompatible amb -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2783,8 +2989,8 @@ Address: %4 <translation>Especifica un fitxer de moneder (dins del directori de dades)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Això s'així per a eines de proves de regressió per al desenvolupament d'aplicacions.</translation> + <source>Use UPnP to map the listening port (default: %u)</source> + <translation>Utilitza UPnP per a mapejar el port d'escolta (per defecte: %u)</translation> </message> <message> <source>Verifying blocks...</source> @@ -2803,6 +3009,10 @@ Address: %4 <translation>Opcions de moneder:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Avís: esta versió és obsoleta; cal actualitzar-la!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation> </message> @@ -2831,6 +3041,10 @@ Address: %4 <translation>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)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Descobreix l'adreça IP pròpia (per defecte: 1 quan s'escolta i no -externalip o -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation> </message> @@ -2847,22 +3061,73 @@ Address: %4 <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la transmissió (per defecte: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la creació de la transacció (per defecte: %s)</translation> + <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> + <translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencen a confirmar-se en una mitja de n blocs (per defecte: %u)</translation> + </message> + <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> + <translation>Import no vàlid per a -maxtxfee=<amount>: '%s' (cal que siga com a mínim la comissió de minrelay de %s per evitar que les comissions s'encallin)</translation> + </message> + <message> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meues (per defecte: %u)</translation> + </message> + <message> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Poda configurada per sota el mínim de %d MB. Feu servir un nombre superior.</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation> </message> <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Genera a l'atzar credencials per a cada connexió proxy. Això habilita l'aïllament del flux de Tor (per defecte: %u)</translation> + </message> + <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d)</translation> </message> <message> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> + <translation>Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d)</translation> + </message> + <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>L'import de la transacció és massa petit per enviar-la després que se'n deduïsca la comissió</translation> + </message> + <message> <source>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.</source> <translation>Este producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit <https://www.openssl.org/> i programari criptogràfic escrit per Eric Young i programari UPnP escrit per Thomas Bernard.</translation> </message> <message> + <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: +%s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +The username and password MUST NOT be the same. +If the file does not exist, create it with owner-readable-only file permissions. +It is also recommended to set alertnotify so you are notified of problems; +for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com +</source> + <translation>Per utilitzar bitcoind, o l'opció de serviddor de bitcoin-qt, heu de definir una rpcpassword en el fitxer de configuració: +%s +Es recomana que utilitzeu la contrasenya aleatòria següent: +rpcuser=bitcoinrpc +rpcpassword=%s +(no cal que recordeu la contrasenya) +El nom d'usuari i la contrasenya NO han de ser els mateixos. +Si el fitxer no existeix, creeu-ne un amb permisos de lectura només per al seu propietari. +Es recomana definir alertnotify per tal de ser notificat de qualsevol problema; +per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</translation> + </message> + <message> + <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>Avís: s'ha especificat un -maxtxfee molt alt! Comissions tan grans podrien pagar-se en una única transacció.</translation> + </message> + <message> <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> <translation>Avís: comproveu que la data i hora del vostre ordinador siguen correctes! Si el vostre rellotge no és correcte, el Bitcoin Core no funcionarà correctament.</translation> </message> @@ -2871,10 +3136,34 @@ Address: %4 <translation>Els iguals en la llista blanca no poden ser bandejats per DoS i es transmetran sempre llurs transaccions, fins i tot si ja són a la mempool. Això és útil, p. ex., per a una passarel·la</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Cal que torneu a construir la base de dades fent servir -reindex per tornar al mode no podat. Això tornarà a baixar la cadena de blocs sencera</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(per defecte: %u)</translation> + </message> + <message> + <source>Accept public REST requests (default: %u)</source> + <translation>Accepta sol·licituds REST públiques (per defecte: %u)</translation> + </message> + <message> + <source>Activating best chain...</source> + <translation>S'està activant la millor cadena...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>No es pot executar amb un moneder en mode poda.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Tria el directori de dades a l'inici (per defecte: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Connecta a través del proxy SOCKS5</translation> </message> @@ -2891,6 +3180,10 @@ Address: %4 <translation>Error en carregar wallet.dat: el moneder requereix una versió més nova del Bitcoin core</translation> </message> <message> + <source>Error reading from database, shutting down.</source> + <translation>Error en llegir la base de dades, tancant.</translation> + </message> + <message> <source>Error: Unsupported argument -tor found, use -onion.</source> <translation>Error: s'ha trobat un argument -tor no acceptat. Feu servir -onion.</translation> </message> @@ -2907,6 +3200,10 @@ Address: %4 <translation>Ha fallat la inicialització de la comprovació de validesa. El Bitcoin Core s'està parant.</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Import no vàlid per a -maxtxfee=<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Import no vàlid per a -minrelaytxfee=<amount>: «%s»</translation> </message> @@ -2923,6 +3220,10 @@ Address: %4 <translation>S'ha especificat una màscara de xarxa no vàlida a -whitelist: «%s»</translation> </message> <message> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Manté com a màxim <n> transaccions no connectables en memòria (per defecte: %u)</translation> + </message> + <message> <source>Need to specify a port with -whitebind: '%s'</source> <translation>Cal especificar un port amb -whitebind: «%s»</translation> </message> @@ -2939,22 +3240,42 @@ Address: %4 <translation>Opcions del servidor RPC:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Descarta a l'atzar 1 de cada <n> missatges de la xarxa</translation> + <source>RPC support for HTTP persistent connections (default: %d)</source> + <translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation> + </message> + <message> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Introdueix incertesa en 1 de cada <n> missatges de la xarxa</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Rep i mostra avisos de la xarxa P2P (per defecte: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Envia informació de traça/depuració a la consola en comptes del fitxer debug.log</translation> </message> <message> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Envia les transaccions com a transaccions de comissió zero sempre que siga possible (per defecte: %u) </translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Mostra totes les opcions de depuració (ús: --help --help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Mostra la finestra de benvinguda a l'inici (per defecte: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Redueix el fitxer debug.log durant l'inici del client (per defecte: 1 quan no -debug)</translation> </message> @@ -2963,6 +3284,14 @@ Address: %4 <translation>Ha fallat la signatura de la transacció</translation> </message> <message> + <source>Start minimized</source> + <translation>Inicia minimitzat</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Això és programari experimental.</translation> </message> @@ -2975,10 +3304,18 @@ Address: %4 <translation>Els imports de les transaccions han de ser positius</translation> </message> <message> + <source>Transaction too large for fee policy</source> + <translation>Transacció massa gran per a la política de comissions</translation> + </message> + <message> <source>Transaction too large</source> <translation>La transacció és massa gran</translation> </message> <message> + <source>UI Options:</source> + <translation>Opcions d'interfície:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>No s'ha pogut vincular a %s en este ordinador (la vinculació ha retornat l'error %s)</translation> </message> @@ -2999,10 +3336,6 @@ Address: %4 <translation>Avís</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Avís: esta versió està obsoleta. És necessari actualitzar-la!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Avís: s'ha ignorat l'argument no acceptat de -benchmark. Feu servir -debug=bench.</translation> </message> @@ -3059,14 +3392,138 @@ Address: %4 <translation>Error en carregar wallet.dat: Moneder corrupte</translation> </message> <message> + <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> + <translation>(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)</translation> + </message> + <message> + <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> + <translation>Com d'exhaustiva és la verificació de blocs del -checkblocks (0-4, per defecte: %u)</translation> + </message> + <message> + <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> + <translation>Manté un índex complet de transaccions, utilitzat per la crida rpc getrawtransaction (per defecte: %u)</translation> + </message> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Nombre de segons necessaris perquè els iguals de comportament qüestionable puguen tornar a connectar-se (per defecte: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Informació d'eixida de la depuració (per defecte: %u, proporcionar <category> és opcional)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor (per defecte: %s)</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(per defecte: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Xifrats acceptables (per defecte: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation> + </message> + <message> <source>Error loading wallet.dat</source> <translation>Error en carregar wallet.dat</translation> </message> <message> + <source>Generate coins (default: %u)</source> + <translation>Genera monedes (per defecte: %u)</translation> + </message> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Quants blocs per comprovar a l'inici (per defecte: %u, 0 = tots)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>Inclou l'adreça IP a l'eixida de depuració (per defecte: %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <translation>Adreça -proxy invalida: '%s'</translation> </message> <message> + <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> + <translation>Escolta les connexions JSON-RPC en <port> (per defecte: %u o testnet: %u)</translation> + </message> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Escolta les connexions en <port> (per defecte: %u o testnet: %u)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Manté com a màxim <n> connexions a iguals (per defecte: %u)</translation> + </message> + <message> + <source>Make the wallet broadcast transactions</source> + <translation>Fes que el moneder faça difusió de les transaccions</translation> + </message> + <message> + <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> + <translation>Memòria intermèdia màxima de recepció per connexió, <n>*1000 bytes (per defecte: %u)</translation> + </message> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <translation>Memòria intermèdia màxima d'enviament per connexió, <n>*1000 bytes (per defecte: %u)</translation> + </message> + <message> + <source>Prepend debug output with timestamp (default: %u)</source> + <translation>Posa davant de l'eixida de depuració una marca horària (per defecte: %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>Retransmet i mina les transaccions de l'operador (per defecte: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <translation>Retransmet multisig no P2SH (per defecte: %u)</translation> + </message> + <message> + <source>Server certificate file (default: %s)</source> + <translation>Fitxer de certificat del servidor (per defecte: %s)</translation> + </message> + <message> + <source>Server private key (default: %s)</source> + <translation>Clau privada del servidor (per defecte: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Defineix la mida clau disponible a <n> (per defecte: %u)</translation> + </message> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Defineix la mida de bloc mínima en bytes (per defecte: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <translation>Defineix el nombre de fils a crides de servei RPC (per defecte: %d)</translation> + </message> + <message> + <source>Specify configuration file (default: %s)</source> + <translation>Especifica el fitxer de configuració (per defecte: %s)</translation> + </message> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Especifica el temps d'espera de la connexió en milisegons (mínim: 1, per defecte: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Especifica el fitxer pid (per defecte: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <translation>Gasta el canvi no confirmat en enviar les transaccions (per defecte: %u)</translation> + </message> + <message> + <source>Threshold for disconnecting misbehaving peers (default: %u)</source> + <translation>Llindar per a desconnectar els iguals de comportament qüestionable (per defecte: %u)</translation> + </message> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Xarxa desconeguda especificada a -onlynet: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index 52d93d59f5..898b7f33b3 100644 --- a/src/qt/locale/bitcoin_ca_ES.ts +++ b/src/qt/locale/bitcoin_ca_ES.ts @@ -1,4 +1,4 @@ -<TS language="ca_ES" version="2.1"> +<TS language="ca_ES" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ <translation>Canvia la contrasenya</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Introduïu tant la contrasenya antiga com la nova del moneder.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Confirma l'encriptació del moneder</translation> </message> @@ -172,6 +168,10 @@ <translation>Esteu segur que voleu encriptar el vostre moneder?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>IMPORTANT: Tota copia de seguretat que hàgiu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder.</translation> </message> @@ -188,8 +188,8 @@ <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin es tancarà ara per acabar el procés d'encriptació. Recordeu que encriptar el moneder no protegeix completament els bitcoins de ser robats per programari maliciós instal·lat a l'ordinador.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Introduïu la contrasenya antiga i la contrasenya nova al moneder.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>Envia monedes a una adreça Bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Modifica les opcions de configuració per bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Realitza una còpia de seguretat del moneder a una altra ubicació</translation> </message> @@ -403,6 +399,10 @@ <translation>&Quant al Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modifica les opcions de configuració del Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Mostra la llista d'adreces d'enviament i etiquetes utilitzades</translation> </message> @@ -431,6 +431,10 @@ <translation>No hi ha cap font de bloc disponible...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>S'han processat %n bloc de l'historial de transacció.</numerusform><numerusform>S'han processat %n blocs de l'historial de transacció.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation> </message> @@ -478,15 +482,41 @@ <source>Up to date</source> <translation>Al dia</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>S'ha processat %n bloc de l'historial de transacció.</numerusform><numerusform>S'han processat %n blocs de l'historial de transacció.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>S'està posant al dia ...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Data: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Import: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tipus: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Etiqueta: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Adreça: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Transacció enviada</translation> </message> @@ -495,14 +525,6 @@ <translation>Transacció entrant</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Data: %1\nImport: %2\n Tipus: %3\n Adreça: %4\n</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>El moneder està <b>encriptat</b> i actualment <b>desbloquejat</b></translation> </message> @@ -693,6 +715,18 @@ Address: %4 <translation>cap</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Aquesta etiqueta es torna en vermell si la transacció és superior a 1000 bytes.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Aquesta etiqueta es torna en vermell si la propietat és inferior que la «mitjana».</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Aquesta etiqueta es torna vermella si el destinatari rep un import inferior de %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Pot variar +/- %1 satoshi(s) per entrada.</translation> </message> @@ -705,10 +739,6 @@ Address: %4 <translation>no</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Aquesta etiqueta es posa de color vermell si la mida de la transacció és més gran de 1000 bytes.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Això comporta una comissió d'almenys %1 per kB.</translation> </message> @@ -721,14 +751,6 @@ Address: %4 <translation>Les transaccions amb una major prioritat són més propenses a ser incloses en un bloc.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Aquesta etiqueta es torna vermella si la prioritat és menor que «mitjana».</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Aquesta etiqueta es torna vermella si qualsevol destinatari rep un import inferior a %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(sense etiqueta)</translation> </message> @@ -849,30 +871,6 @@ Address: %4 <source>command-line options</source> <translation>Opcions de la línia d'ordres</translation> </message> - <message> - <source>UI options</source> - <translation>Opcions de IU</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Inicia minimitzat</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostra la finestra de benvinguda a l'inici (per defecte: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Tria el directori de dades a l'inici (per defecte: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -955,14 +953,6 @@ Address: %4 <translation>&Principal</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Inicia automàticament el Bitcoin després de l'inici de sessió del sistema.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Inicia el Bitcoin a l'inici de sessió del sistema.</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Mida de la memòria cau de la base de &dades</translation> </message> @@ -987,6 +977,14 @@ Address: %4 <translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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ú. </translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>La interfície d'usuari pot definir-se des d'aquí. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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 |.</translation> </message> @@ -1011,6 +1009,14 @@ Address: %4 <translation>&Xarxa</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Inicia el Bitcoin Core en inciar el sistema</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = deixa tants nuclis lliures)</translation> </message> @@ -1075,10 +1081,6 @@ Address: %4 <translation>&Minimitza a la barra d'aplicacions en comptes de la barra de tasques</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimitza en comptes de sortir de la aplicació al tancar la finestra. Quan aquesta opció està activa, la aplicació només es tancarà al seleccionar Sortir al menú.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimitza en tancar</translation> </message> @@ -1091,10 +1093,6 @@ Address: %4 <translation>&Llengua de la interfície d'usuari:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Aquí podeu definir la llengua de l'aplicació. Aquesta configuració tindrà efecte una vegada es reiniciï Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Unitats per mostrar els imports en:</translation> </message> @@ -1131,8 +1129,8 @@ Address: %4 <translation>Cal reiniciar el client per activar els canvis.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>S'aturarà el client, voleu procedir?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>S'aturarà el client. Voleu procedir?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1217,10 +1215,6 @@ Address: %4 <source>Current total balance in watch-only addresses</source> <translation>Balanç total actual en adreces de només lectura</translation> </message> - <message> - <source>out of sync</source> - <translation>Fora de sincronia</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1241,10 +1235,6 @@ Address: %4 <translation>La xarxa de la sol·licitud de pagament no coincideix amb la xarxa del client.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>La sol·licitud de pagament ha caducat.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>La sol·licitud de pagament no està inicialitzada.</translation> </message> @@ -1277,10 +1267,18 @@ Address: %4 <translation>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.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>La sol·licitud de pagament ha vençut.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Sol·licitud de pagament no vàlida.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Reemborsament de %1</translation> </message> @@ -1320,8 +1318,8 @@ Address: %4 <translation>Agent d'usuari</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Adreça / nom de l'ordinador</translation> + <source>Node/Service</source> + <translation>Node/Servei</translation> </message> <message> <source>Ping Time</source> @@ -1355,14 +1353,6 @@ Address: %4 <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>XARXA</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>DESCONEGUT</translation> - </message> - <message> <source>None</source> <translation>Cap</translation> </message> @@ -1453,6 +1443,10 @@ Address: %4 <translation>Nombre de blocs actuals</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>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.</translation> + </message> + <message> <source>Received</source> <translation>Rebut</translation> </message> @@ -1521,6 +1515,10 @@ Address: %4 <translation>Temps de ping</translation> </message> <message> + <source>Time Offset</source> + <translation>Diferència horària</translation> + </message> + <message> <source>Last block time</source> <translation>Últim temps de bloc</translation> </message> @@ -1561,16 +1559,12 @@ Address: %4 <translation>Fitxer de registre de depuració</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Obre el fitxer de registre de depuració de Bitcoin del directori de dades actual. Això pot trigar uns quants segons per a fitxers de registre grans.</translation> - </message> - <message> <source>Clear console</source> <translation>Neteja la consola</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Us donem la benvinguda a la consola RPC de Bitcoin</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Us donem la benviguda a la consola RPC del Bitcoin Core.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1861,14 +1855,6 @@ Address: %4 <translation>redueix els paràmetres de comissió</translation> </message> <message> - <source>Minimize</source> - <translation>Minimitza</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation> - </message> - <message> <source>per kilobyte</source> <translation>per kilobyte</translation> </message> @@ -1877,6 +1863,10 @@ Address: %4 <translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «total com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation> </message> <message> + <source>Hide</source> + <translation>Amaga</translation> + </message> + <message> <source>total at least</source> <translation>total com a mínim</translation> </message> @@ -1997,10 +1987,6 @@ Address: %4 <translation>o</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>L'adreça de destinatari no és vàlida, si us plau comprovi-la.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>L'import a pagar ha de ser major que 0.</translation> </message> @@ -2013,10 +1999,6 @@ Address: %4 <translation>El total excedeix el teu balanç quan s'afegeix la comissió a la transacció %1.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>S'ha trobat una adreça duplicada, tan sols es pot enviar a cada adreça un cop per ordre de enviament.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Ha fallat la creació de la transacció!</translation> </message> @@ -2025,16 +2007,28 @@ Address: %4 <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> - <translation>Una comissió superior a %1 es considera una comissió excessiva.</translation> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Una comissió superior a %1 es considera una comissió absurdament alta.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>La sol·licitud de pagament ha vençut.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation> </message> <message> <source>Pay only the minimum fee of %1</source> <translation>Paga només la comissió mínima de %1</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Estimat per a començar la confirmació en %1 bloc(s).</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2108,12 +2102,24 @@ Address: %4 <translation>Elimina aquesta entrada</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>La comissió es deduirà de l'import que s'enviarà. El destinatari rebrà menys bitcoins que les que introduïu al camp d'import. Si se seleccionen múltiples destinataris, la comissió es dividirà per igual.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>S&ubstreu la comissió de l'import</translation> + </message> + <message> <source>Message:</source> <translation>Missatge:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Aquesta és una sol·licitud de pagament verificada.</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Aquesta és una sol·licitud de pagament no autenticada.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Aquesta és una sol·licitud de pagament autenticada.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2124,10 +2130,6 @@ Address: %4 <translation>Un missatge que s'ha adjuntat al bitcoin: URI que s'emmagatzemarà amb la transacció per a la vostra referència. Nota: el missatge no s'enviarà a través de la xarxa Bitcoin.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Aquesta és una sol·licitud de pagament no verificada.</translation> - </message> - <message> <source>Pay To:</source> <translation>Paga a:</translation> </message> @@ -2158,8 +2160,8 @@ Address: %4 <translation>&Signa el missatge</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Podeu signar missatges amb la vostra adreça per provar que són vostres. Aneu amb compte no signar qualsevol cosa, ja que els atacs de pesca electrònica (phishing) poden provar de confondre-us perquè els signeu amb la vostra identitat. Només signeu als documents completament detallats amb què hi esteu d'acord.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Podeu signar missatges/acords amb les vostres adreces per provar que rebeu les bitcoins que s'hi envien. Aneu amb compte no signar res que sigui vague o aleatori, perquè en alguns atacs de suplantació es pot provar que hi signeu la vostra identitat. Només signeu aquelles declaracions completament detallades en què hi esteu d'acord. </translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2214,8 +2216,8 @@ Address: %4 <translation>&Verifica el missatge</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Introdueixi l'adreça signant, missatge (assegura't que copies salts de línia, espais, tabuladors, etc excactament tot el text) i la signatura a sota per verificar el missatge. Per evitar ser enganyat per un atac home-entre-mig, vés amb compte de no llegir més en la signatura del que hi ha al missatge signat mateix.</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Introduïu l'adreça del receptor, el missatge (assegureu-vos de copiar els salts de línia, espais, tabuladors, etc. exactament) i signatura de sota per verificar el missatge. Tingueu cura de no llegir més en la signatura del que està al missatge signat, per evitar ser enganyat per un atac d'home-en-el-mig. Tingueu en compte que això només demostra que la part que signa rep amb l'adreça, i no es pot provar l'enviament de qualsevol transacció!</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2481,10 +2483,6 @@ Address: %4 <translation>Tipus</translation> </message> <message> - <source>Address</source> - <translation>Adreça</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Immadur (%1 confirmacions, serà disponible després de %2)</translation> </message> @@ -2513,6 +2511,10 @@ Address: %4 <translation>Fora de línia</translation> </message> <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Sense confirmar</translation> </message> @@ -2569,8 +2571,8 @@ Address: %4 <translation>Si està implicada o no una adreça només de lectura en la transacció.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Adreça del destinatari de la transacció.</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Intenció/propòsit de la transacció definida per l'usuari.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2823,16 +2825,16 @@ Address: %4 <translation>Distribuït sota llicència de programari MIT. Vegeu el fitxer acompanyant COPYING o <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Entra en el mode de proves de regressió, que utilitza una cadena especial en què els blocs poden resoldre's al moment.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Executa una ordre quan una transacció del moneder canviï (%s en cmd es canvia per TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>En aquest mode -genproclimit controla quants blocs es generen immediatament.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Redueix els requeriments d'emmagatzemament podant (suprimint) els blocs antics. Aquest mode inhabilita l'ús de moneders i és incompatible amb -tindex. Avís: Revertir aquesta configuració comporta tornar a baixar la cadena de blocs sencera. (per defecte: 0 = inhabilita la poda de blocs, >%u = mida objectiu en MiB per utilitzar els fitxers de blocs)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2847,6 +2849,14 @@ Address: %4 <translation>No es pot enllaçar %s a aquest ordinador. El Bitcoin Core probablement ja estigui executant-s'hi.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Avís: el -paytxfee és molt elevat! Aquesta és la comissió de transacció que pagareu si envieu una transacció.</translation> </message> @@ -2903,10 +2913,6 @@ Address: %4 <translation>Opcions de depuració/proves:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Descobreix la pròpia adreça IP (per defecte: 1 quan escoltant i no -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>No carreguis el moneder i inhabilita les crides RPC del moneder</translation> </message> @@ -2967,8 +2973,12 @@ Address: %4 <translation>Només connecta als nodes de la xarxa <net> (ipv4, ipv6 o onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers actuals blk000??.dat</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>La poda no es pot configurar amb un valor negatiu.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>El mode de poda és incompatible amb -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2983,10 +2993,6 @@ Address: %4 <translation>Especifica un fitxer de moneder (dins del directori de dades)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Això es així per a eines de proves de regressió per al desenvolupament d'aplicacions.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Utilitza UPnP per a mapejar el port d'escolta (per defecte: %u)</translation> </message> @@ -3007,6 +3013,10 @@ Address: %4 <translation>Opcions de moneder:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Avís: aquesta versió és obsoleta; cal actualitzar-la!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation> </message> @@ -3031,14 +3041,14 @@ Address: %4 <translation>No es pot obtenir un bloqueig del directori de dades %s. El Bitcoin Core probablement ja s'estigui executant.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Limita contínuament la freqüència de les transaccions gratuïtes a <n>*1000 bytes per minut (per defecte: %u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>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)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Descobreix l'adreça IP pròpia (per defecte: 1 quan s'escolta i no -externalip o -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation> </message> @@ -3055,10 +3065,6 @@ Address: %4 <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la transmissió (per defecte: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la creació de la transacció (per defecte: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencin a confirmar-se en una mitja de n blocs (per defecte: %u)</translation> </message> @@ -3071,16 +3077,16 @@ Address: %4 <translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meves (per defecte: %u)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>Comissions totals màximes que s'utilitzaran en una transacció d'un únic moneder. Si es defineix un valor massa baix les transaccions més grans poden interrompre's (per defecte: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Poda configurada per sota el mínim de %d MB. Feu servir un nombre superior.</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>Es requereix una prioritat alta per retransmetre transaccions gratuïtes o de baixa comissió (per defecte:%u)</translation> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Genera a l'atzar credencials per a cada connexió proxy. Això habilita l'aïllament del flux de Tor (per defecte: %u)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3091,6 +3097,10 @@ Address: %4 <translation>Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>L'import de la transacció és massa petit per enviar-la després que se'n dedueixi la comissió</translation> + </message> + <message> <source>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.</source> <translation>Aquest producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit <https://www.openssl.org/> i programari criptogràfic escrit per Eric Young i programari UPnP escrit per Thomas Bernard.</translation> </message> @@ -3130,14 +3140,34 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Els iguals en la llista blanca no poden ser bandejats per DoS i es transmetran sempre llurs transaccions, fins i tot si ja són a la mempool. Això és útil, p. ex., per a una passarel·la</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Cal que torneu a construir la base de dades fent servir -reindex per tornar al mode no podat. Això tornarà a baixar la cadena de blocs sencera</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(per defecte: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Accepta sol·licituds REST públiques (per defecte: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>S'està activant la millor cadena...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>No es pot executar amb un moneder en mode poda.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Tria el directori de dades a l'inici (per defecte: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Connecta a través del proxy SOCKS5</translation> </message> @@ -3218,12 +3248,12 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Descarta a l'atzar 1 de cada <n> missatges de la xarxa</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Introdueix incertesa en 1 de cada <n> missatges de la xarxa</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Rep i mostra avisos de la xarxa P2P (per defecte: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3234,10 +3264,22 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Envia les transaccions com a transaccions de comissió zero sempre que sigui possible (per defecte: %u) </translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Mostra totes les opcions de depuració (ús: --help --help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Mostra la finestra de benvinguda a l'inici (per defecte: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Redueix el fitxer debug.log durant l'inici del client (per defecte: 1 quan no -debug)</translation> </message> @@ -3246,6 +3288,14 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Ha fallat la signatura de la transacció</translation> </message> <message> + <source>Start minimized</source> + <translation>Inicia minimitzat</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Això és programari experimental.</translation> </message> @@ -3266,6 +3316,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>La transacció és massa gran</translation> </message> <message> + <source>UI Options:</source> + <translation>Opcions d'interfície:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>No s'ha pogut vincular a %s en aquest ordinador (la vinculació ha retornat l'error %s)</translation> </message> @@ -3286,10 +3340,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Avís</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Avís: aquesta versió està obsoleta. És necessari actualitzar-la!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Avís: s'ha ignorat l'argument no acceptat de -benchmark. Feu servir -debug=bench.</translation> </message> @@ -3350,18 +3400,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>(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)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Buida l'activitat de la base de dades de la memòria disponible al registre del disc cada <n> megabytes (per defecte: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Com d'exhaustiva és la verificació de blocs del -checkblocks (0-4, per defecte: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Enregistreu la prioritat de la transacció i la comissió per kB en minar blocs (per defecte: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Manté un índex complet de transaccions, utilitzat per la crida rpc getrawtransaction (per defecte: %u)</translation> </message> @@ -3390,18 +3432,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Inhabilita el mode segur, sobreescriu un esdeveniment de mode segur real (per defecte: %u) </translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Error en carregar wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Força el mode segur (per defecte: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Genera monedes (per defecte: %u)</translation> </message> @@ -3418,10 +3452,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Adreça -proxy invalida: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Limita la mida de la cau de signatura a <n> entrades (per defecte: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Escolta les connexions JSON-RPC en <port> (per defecte: %u o testnet: %u)</translation> </message> @@ -3434,6 +3464,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Manté com a màxim <n> connexions a iguals (per defecte: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Fes que el moneder faci difusió de les transaccions</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Memòria intermèdia màxima de recepció per connexió, <n>*1000 bytes (per defecte: %u)</translation> </message> @@ -3442,10 +3476,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Memòria intermèdia màxima d'enviament per connexió, <n>*1000 bytes (per defecte: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Només accepta els punts de control integrats que coincideixen amb la cadena de blocs (per defecte: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Posa davant de la sortida de depuració una marca horària (per defecte: %u)</translation> </message> @@ -3458,10 +3488,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Retransmet multisig no P2SH (per defecte: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Executa un fil per buidar el moneder periòdicament (per defecte: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Fitxer de certificat del servidor (per defecte: %s)</translation> </message> @@ -3482,10 +3508,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Defineix el nombre de fils a crides de servei RPC (per defecte: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Defineix el senyalador DB_PRIVATE en l'entorn db del moneder (per defecte: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Especifica el fitxer de configuració (per defecte: %s)</translation> </message> @@ -3502,10 +3524,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Gasta el canvi no confirmat en enviar les transaccions (per defecte: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Atura l'execució després d'importar blocs del disc (per defecte: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Llindar per a desconnectar els iguals de comportament qüestionable (per defecte: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_cmn.ts b/src/qt/locale/bitcoin_cmn.ts index 3286f12698..37c937b864 100644 --- a/src/qt/locale/bitcoin_cmn.ts +++ b/src/qt/locale/bitcoin_cmn.ts @@ -1,6 +1,10 @@ -<TS language="cmn" version="2.1"> +<TS language="cmn" version="2.0"> <context> <name>AddressBookPage</name> + <message> + <source>Create a new address</source> + <translation>创建新地址</translation> + </message> </context> <context> <name>AddressTableModel</name> diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index 04cd96f425..6e7ffec27f 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -1,4 +1,4 @@ -<TS language="cs" version="2.1"> +<TS language="cs" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ <translation>Změň heslo</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Zadej staré a nové heslo k peněžence.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Potvrď zašifrování peněženky</translation> </message> @@ -172,6 +168,10 @@ <translation>Jsi si jistý, že chceš peněženku zašifrovat?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -188,8 +188,8 @@ <translation>Zadej nové heslo k peněžence.<br/>Použij <b>alespoň deset náhodných znaků</b> nebo <b>alespoň osm slov</b>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin se teď ukončí, aby dokončil zašifrování. Pamatuj však, že pouhé zašifrování peněženky úplně nezabraňuje krádeži tvých bitcoinů malwarem, kterým se může počítač nakazit.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Zadej staré a nové heslo k peněžence.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>Pošli mince na Bitcoinovou adresu</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Uprav nastavení Bitcoinu</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Zazálohuj peněženku na jiné místo</translation> </message> @@ -403,6 +399,10 @@ <translation>O &Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Uprav nastavení Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Ukaž seznam použitých odesílacích adres a jejich označení</translation> </message> @@ -431,6 +431,10 @@ <translation>Není dostupný žádný zdroj bloků...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Zpracován %n blok transakční historie.</numerusform><numerusform>Zpracovány %n bloky transakční historie.</numerusform><numerusform>Zpracováno %n bloků transakční historie.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hodinu</numerusform><numerusform>%n hodiny</numerusform><numerusform>%n hodin</numerusform></translation> </message> @@ -478,35 +482,49 @@ <source>Up to date</source> <translation>Aktuální</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>Zpracován %n blok transakční historie.</numerusform><numerusform>Zpracovány %n bloky transakční historie.</numerusform><numerusform>Zpracováno %n bloků transakční historie.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Stahuji...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Odeslané transakce</translation> + <source>Date: %1 +</source> + <translation>Datum: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Příchozí transakce</translation> + <source>Amount: %1 +</source> + <translation>Částka: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Datum: %1 -Částka: %2 -Typ: %3 -Adresa: %4 + <translation>Typ: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Označení: %1 </translation> </message> <message> + <source>Address: %1 +</source> + <translation>Adresa: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Odeslané transakce</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Příchozí transakce</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Peněženka je <b>zašifrovaná</b> a momentálně <b>odemčená</b></translation> </message> @@ -697,6 +715,18 @@ Adresa: %4 <translation>žádná</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Popisek zčervená, pokud je velikost transakce větší než 1000 bajtů.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Popisek zčervená, pokud je priorita menší než „střední“.</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Popisek zčervená, pokud má některý příjemce obdržet částku menší než %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Může se lišit o +/– %1 satoshi na každý vstup.</translation> </message> @@ -709,10 +739,6 @@ Adresa: %4 <translation>ne</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Popisek zčervená, pokud je velikost transakce větší než 1000 bajtů.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>To znamená, že je vyžadován poplatek alespoň %1 za kB.</translation> </message> @@ -725,14 +751,6 @@ Adresa: %4 <translation>Transakce s vyšší prioritou mají větší šanci na zařazení do bloku.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Popisek zčervená, pokud je priorita menší než „střední“.</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Popisek zčervená, pokud má některý příjemce obdržet částku menší než %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(bez označení)</translation> </message> @@ -853,30 +871,6 @@ Adresa: %4 <source>command-line options</source> <translation>možnosti příkazové řádky</translation> </message> - <message> - <source>UI options</source> - <translation>Možnosti UI</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Nastavit jazyk, například "de_DE" (výchozí: systémové nastavení)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Nastartovat minimalizovaně</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Nastavit kořenové SSL certifikáty pro platební požadavky (výchozí: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Zobrazit startovací obrazovku (výchozí: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Zvolit adresář pro data při startu (výchozí: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -959,14 +953,6 @@ Adresa: %4 <translation>&Hlavní</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Automaticky spustí Bitcoin po přihlášení do systému.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>S&pustit Bitcoin po přihlášení do systému</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Velikost &databázové cache</translation> </message> @@ -991,6 +977,14 @@ Adresa: %4 <translation>IP adresa proxy (např. IPv4: 127.0.0.1/IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Zavřením se aplikace minimalizuje. Pokud je tato volba zaškrtnuta, tak se aplikace ukončí pouze zvolením Konec v menu.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Tady lze nastavit jazyk uživatelského rozhraní. Nastavení se projeví až po restartování Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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 |.</translation> </message> @@ -1015,6 +1009,14 @@ Adresa: %4 <translation>&Síť</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Automaticky spustí Bitcoin Core po přihlášení do systému.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>S&pustit Bitcoin Core po přihlášení do systému</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = automaticky, <0 = nechat daný počet jader volný, výchozí: 0)</translation> </message> @@ -1079,10 +1081,6 @@ Adresa: %4 <translation>&Minimalizovávat do ikony v panelu</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Zavřením se aplikace minimalizuje. Pokud je tato volba zaškrtnuta, tak se aplikace ukončí pouze zvolením Konec v menu.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>Za&vřením minimalizovat</translation> </message> @@ -1095,10 +1093,6 @@ Adresa: %4 <translation>&Jazyk uživatelského rozhraní:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Tady lze nastavit jazyk uživatelského rozhraní. Nastavení se projeví až po restartování Bitcoinu.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>J&ednotka pro částky:</translation> </message> @@ -1135,7 +1129,7 @@ Adresa: %4 <translation>K aktivaci změn je potřeba restartovat klienta.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> + <source>Client will be shut down. Do you want to proceed?</source> <translation>Klient se vypne, chceš pokračovat?</translation> </message> <message> @@ -1221,10 +1215,6 @@ Adresa: %4 <source>Current total balance in watch-only addresses</source> <translation>Aktuální stav účtu sledovaných adres</translation> </message> - <message> - <source>out of sync</source> - <translation>nesynchronizováno</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1245,10 +1235,6 @@ Adresa: %4 <translation>Síť platebního požadavku neodpovídá síti klienta.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Platební požadavek vypršel.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Platební požadavek není zahájený.</translation> </message> @@ -1281,10 +1267,18 @@ Adresa: %4 <translation>Soubor platebního požadavku nejde přečíst nebo zpracovat! Příčinou může být špatný soubor platebního požadavku.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Platební požadavek vypršel.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Neověřené platební požadavky k uživatelským platebním skriptům nejsou podporované.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Neplatný platební požadavek.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Vrácení peněz od %1</translation> </message> @@ -1324,8 +1318,8 @@ Adresa: %4 <translation>Typ klienta</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Adresa/Název hostitele</translation> + <source>Node/Service</source> + <translation>Uzel/Služba</translation> </message> <message> <source>Ping Time</source> @@ -1359,14 +1353,6 @@ Adresa: %4 <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>SÍŤ</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>NEZNÁMÁ</translation> - </message> - <message> <source>None</source> <translation>Žádné</translation> </message> @@ -1457,6 +1443,10 @@ Adresa: %4 <translation>Aktuální počet bloků</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>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.</translation> + </message> + <message> <source>Received</source> <translation>Přijato</translation> </message> @@ -1525,6 +1515,10 @@ Adresa: %4 <translation>Odezva</translation> </message> <message> + <source>Time Offset</source> + <translation>Časový posun</translation> + </message> + <message> <source>Last block time</source> <translation>Čas posledního bloku</translation> </message> @@ -1565,16 +1559,12 @@ Adresa: %4 <translation>Soubor s ladicími záznamy</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Otevři soubor s ladicími záznamy Bitcoinu z aktuálního datového adresáře. U velkých logů to může pár vteřin zabrat.</translation> - </message> - <message> <source>Clear console</source> <translation>Vyčistit konzoli</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Vítej v Bitcoinové RPC konzoli.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Vítej v RPC konzoli Bitcoin Core.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1865,14 +1855,6 @@ Adresa: %4 <translation>sbal nastavení poplatků</translation> </message> <message> - <source>Minimize</source> - <translation>Skryj</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Pokud je vlastní poplatek nastavený na 1000 satoshi a transakce má pouze 250 bajtů, tak „za kilobajt“ zaplatí poplatek jen 250 satoshi, zatímco „přinejmenším“ zaplatí 1000 satoshi. Pro transakce větší než kilobajt obě možnosti platí za kilobajt.</translation> - </message> - <message> <source>per kilobyte</source> <translation>za kilobajt</translation> </message> @@ -1881,6 +1863,10 @@ Adresa: %4 <translation>Pokud je vlastní poplatek nastavený na 1000 satoshi a transakce má pouze 250 bajtů, tak „za kilobajt“ zaplatí poplatek jen 250 satoshi, zatímco „přinejmenším“ zaplatí 1000 satoshi. Pro transakce větší než kilobajt obě možnosti platí za kilobajt.</translation> </message> <message> + <source>Hide</source> + <translation>Skryj</translation> + </message> + <message> <source>total at least</source> <translation>přinejmenším</translation> </message> @@ -2001,10 +1987,6 @@ Adresa: %4 <translation>nebo</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Adresa příjemce je neplatná, překontroluj ji prosím.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Odesílaná částka musí být větší než 0.</translation> </message> @@ -2017,10 +1999,6 @@ Adresa: %4 <translation>Celková částka při připočítání poplatku %1 překročí stav účtu.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Zaznamenána duplikovaná adresa; každá adresa může být v odesílané platbě pouze jednou.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Vytvoření transakce selhalo!</translation> </message> @@ -2029,16 +2007,28 @@ Adresa: %4 <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> + <source>A fee higher than %1 is considered an absurdly high fee.</source> <translation>Poplatek vyšší než %1 je považován za absurdně vysoký.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Platební požadavek vypršel.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Potvrzování by podle odhadu mělo začít během %n bloku.</numerusform><numerusform>Potvrzování by podle odhadu mělo začít během %n bloků.</numerusform><numerusform>Potvrzování by podle odhadu mělo začít během %n bloků.</numerusform></translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Zaplatit pouze minimální poplatek %1</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Potvrzování by podle odhadu mělo začít během %1 bloků.</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Adresa příjemce je neplatná – překontroluj ji prosím.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Zaznamenána duplicitní adresa: každá adresa by ale měla být použita vždy jen jednou.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2112,11 +2102,23 @@ Adresa: %4 <translation>Smaž tento záznam</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>Poplatek se odečte od posílané částky. Příjemce tak dostane méně bitcoinů, než zadáš do pole Částka. Pokud vybereš více příjemců, tak se poplatek rovnoměrně rozloží.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>&Odečíst poplatek od částky</translation> + </message> + <message> <source>Message:</source> <translation>Zpráva:</translation> </message> <message> - <source>This is a verified payment request.</source> + <source>This is an unauthenticated payment request.</source> + <translation>Tohle je neověřený platební požadavek.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> <translation>Tohle je ověřený platební požadavek.</translation> </message> <message> @@ -2128,10 +2130,6 @@ Adresa: %4 <translation>Zpráva, která byla připojena k bitcoin: URI a která se ti pro přehled uloží k transakci. Poznámka: Tahle zpráva se neposílá s platbou po Bitcoinové síti.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Tohle je neověřený platební požadavek.</translation> - </message> - <message> <source>Pay To:</source> <translation>Komu:</translation> </message> @@ -2162,8 +2160,8 @@ Adresa: %4 <translation>&Podepiš zprávu</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Podepsáním zprávy svými adresami můžeš prokázat, že je skutečně vlastníš. Buď opatrný a nepodepisuj nic vágního; například při phishingových útocích můžeš být lákán, abys něco takového podepsal. Podepisuj pouze zcela úplná a detailní prohlášení, se kterými souhlasíš.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Podepsáním zprávy/smlouvy svými adresami můžeš prokázat, že jsi na ně schopen přijmout bitcoiny. Buď opatrný a nepodepisuj nic vágního nebo náhodného; například při phishingových útocích můžeš být lákán, abys něco takového podepsal. Podepisuj pouze naprosto úplná a detailní prohlášení, se kterými souhlasíš.</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2218,8 +2216,8 @@ Adresa: %4 <translation>&Ověř zprávu</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>K ověření podpisu zprávy zadej podepisující adresu, zprávu (ověř si, že správně kopíruješ zalomení řádků, mezery, tabulátory apod.) a podpis. Dávej pozor na to, abys nezkopíroval do podpisu víc, než co je v samotné podepsané zprávě, abys nebyl napálen man-in-the-middle útokem.</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>K ověření podpisu zprávy zadej adresu příjemce, zprávu (ověř si, že správně kopíruješ zalomení řádků, mezery, tabulátory apod.) a podpis. Dávej pozor na to, abys nezkopíroval do podpisu víc, než co je v samotné podepsané zprávě, abys nebyl napálen man-in-the-middle útokem. Poznamenejme však, že takto lze pouze prokázat, že podepisující je schopný na dané adrese přijmout platbu, ale není možnéprokázat, že odeslal jakoukoli transakci!</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2485,10 +2483,6 @@ Adresa: %4 <translation>Typ</translation> </message> <message> - <source>Address</source> - <translation>Adresa</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Nedozráno (%1 potvrzení, bude k dispozici za %2)</translation> </message> @@ -2517,6 +2511,10 @@ Adresa: %4 <translation>Offline</translation> </message> <message> + <source>Label</source> + <translation>Označení</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Nepotvrzeno</translation> </message> @@ -2573,8 +2571,8 @@ Adresa: %4 <translation>Zda tato transakce zahrnuje i některou sledovanou adresu.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Cílová adresa transakce.</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Uživatelsky určený účel transakce.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2796,7 +2794,7 @@ Adresa: %4 </message> <message> <source>Specify your own public address</source> - <translation>Specifikuj svou veřejnou adresu</translation> + <translation>Udej svou veřejnou adresu</translation> </message> <message> <source>Accept command line and JSON-RPC commands</source> @@ -2827,16 +2825,16 @@ Adresa: %4 <translation>Šířen pod softwarovou licencí MIT, viz přiložený soubor COPYING nebo <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Přepnout do módu testování regresí, který používá speciální řetězec, ve kterém mohou být bloky okamžitě vyřešeny.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Spustit příkaz, když se objeví transakce týkající se peněženky (%s se v příkazu nahradí za TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>V tomto módu -genproclimit určuje, kolik bloků je vygenerováno okamžitě.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Horní hranice pro celkový poplatek za jednu transakci z peněženky; příliš nízká hodnota může zmařit velké transakce (výchozí: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Omezit nároky na úložný prostor prořezáváním (mazáním) starých bloků. V tomto režimu chybí peněženka a rovněž tento režim není slučitelný s -txindex. 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)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2851,6 +2849,14 @@ Adresa: %4 <translation>Nedaří se mi připojit na %s na tomhle počítači. Bitcoin Core už pravděpodobně jednou běží.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>UPOZORNĚNÍ: vygenerováno nezvykle mnoho bloků – přijato %d bloků jen za posledních %d hodin (očekáváno %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>UPOZORNĚNÍ: zkontroluj své spojení do sítě – bylo přijato %d bloků za posledních %d hodin (očekáváno %d)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Upozornění: -paytxfee je nastaveno velmi vysoko! Toto je transakční poplatek, který zaplatíš za každou poslanou transakci.</translation> </message> @@ -2888,7 +2894,7 @@ Adresa: %4 </message> <message> <source>Block creation options:</source> - <translation>Možnosti vytvoření bloku:</translation> + <translation>Možnosti vytváření bloku:</translation> </message> <message> <source>Connect only to the specified node(s)</source> @@ -2907,10 +2913,6 @@ Adresa: %4 <translation>Možnosti ladění/testování:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Zjistit vlastní IP adresu (výchozí: 1, pokud naslouchá a není zadáno -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Nenačítat peněženku a vypnout její RPC volání</translation> </message> @@ -2971,8 +2973,12 @@ Adresa: %4 <translation>Připojovat se pouze k uzlům v <net> síti (ipv4, ipv6 nebo onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Znovu vytvořit index řetězce bloků z aktuálních blk000??.dat souborů</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>Prořezávání nemůže být zkonfigurováno s negativní hodnotou.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Prořezávací režim není kompatibilní s -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2987,16 +2993,12 @@ Adresa: %4 <translation>Udej název souboru s peněženkou (v rámci datového adresáře)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Tohle je určeno pro nástroje na regresní testování a vyvíjení aplikací.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Použít UPnP k namapování naslouchacího portu (výchozí: %u)</translation> </message> <message> <source>Verifying blocks...</source> - <translation>Ověřuji bloky... </translation> + <translation>Ověřuji bloky...</translation> </message> <message> <source>Verifying wallet...</source> @@ -3011,6 +3013,10 @@ Adresa: %4 <translation>Možnosti peněženky:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Upozornění: tahle verze je zastaralá, měl bys ji aktualizovat!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Je třeba přestavět databázi použitím -reindex, aby bylo možné změnit -txindex</translation> </message> @@ -3039,14 +3045,14 @@ Adresa: %4 <translation>Nedaří se mi získat zámek na datový adresář %s. Bitcoin Core pravděpodobně už jednou běží.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Kontinuálně omezovat bezpoplatkové transakce na <n>*1000 bajtů za minutu (výchozí: %u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>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)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Zjistit vlastní IP adresu (výchozí: 1, pokud naslouchá a není zadáno -externalip nebo -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Chyba: Nelze naslouchat příchozí spojení (listen vrátil chybu %s)</translation> </message> @@ -3060,25 +3066,33 @@ Adresa: %4 </message> <message> <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Poplatky (v BTC/Kb) menší než tato hodnota jsou považovány za nulové pro účely přeposílání transakcí (výchozí: %s)</translation> + <translation>Poplatky (v BTC/kB) menší než tato hodnota jsou považovány za nulové pro účely přeposílání transakcí (výchozí: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Poplatky (v BTC/Kb) menší než tato hodnota jsou považovány za nulové pro účely vytváření transakcí (výchozí: %s)</translation> + <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> + <translation>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)</translation> </message> <message> - <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> - <translation>Pokud paytxfee není nastaveno, platit dostatečný poplatek na to, aby byly transakce potvrzeny v průměru během n bloků (výchozí: %u)</translation> + <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> + <translation>Neplatná částka pro -maxtxfee=<amount>: '%s' (musí být alespoň jako poplatek minrelay %s, aby transakce nezůstávaly trčet)</translation> </message> <message> <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> <translation>Maximální velikost dat v transakcích nesoucích data, se kterou jsme ochotni je ještě přeposílat a těžit (výchozí: %u)</translation> </message> <message> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Prořezávání je nastaveno pod minimum %d MB. Použij prosím nějaké vyšší číslo.</translation> + </message> + <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Při nedostatku adres získat další protějšky z DNS (výchozí: 1, pokud není použito -connect)</translation> </message> <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Použít náhodné údaje pro každé proxy spojení. To umožní izolovat nesouvisející datové toky v Toru (výchozí: %u)</translation> + </message> + <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Nastavit maximální velikost prioritních/nízkopoplatkových transakcí v bajtech (výchozí: %d)</translation> </message> @@ -3087,10 +3101,42 @@ Adresa: %4 <translation>Nastavení počtu vláken pro těžení, je-li zapnuté (-1 = všechna jádra, výchozí: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Částka v transakci po odečtení poplatku je příliš malá na odeslání</translation> + </message> + <message> <source>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.</source> <translation>Tento produkt zahrnuje programy vyvinuté OpenSSL Projektem pro použití v OpenSSL Toolkitu <https://www.openssl.org/> a kryptografický program od Erika Younga a program UPnP od Thomase Bernarda.</translation> </message> <message> + <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: +%s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +The username and password MUST NOT be the same. +If the file does not exist, create it with owner-readable-only file permissions. +It is also recommended to set alertnotify so you are notified of problems; +for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com +</source> + <translation>K používání bitcoind nebo volby -server u bitcoin-qt musíš nastavit rpcpassword v konfiguračním souboru: +%s +Je vhodné použít následující náhodné heslo: +rpcuser=bitcoinrpc +rpcpassword=%s +(není potřeba si ho pamatovat) +rpcuser a rpcpassword NESMÍ být stejné. +Pokud konfigurační soubor ještě neexistuje, vytvoř ho tak, aby ho mohl číst pouze vlastník. +Je také doporučeno si nastavit alertnotify, abys byl upozorněn na případné problémy; +například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com +</translation> + </message> + <message> + <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>Upozornění: -maxtxfee je nastaveno velmi vysoko! Takto vysoký poplatek může být zaplacen v jednotlivé transakci.</translation> + </message> + <message> <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> <translation>Upozornění: Zkontroluj, že máš v počítači správně nastavený datum a čas! Pokud jsou nastaveny špatně, Bitcoin Core nebude fungovat správně.</translation> </message> @@ -3099,10 +3145,34 @@ Adresa: %4 <translation>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</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>K návratu k neprořezávacímu režimu je potřeba přestavět databázi použitím -reindex. Také se znovu stáhne celý řetězec bloků</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(výchozí: %u)</translation> + </message> + <message> + <source>Accept public REST requests (default: %u)</source> + <translation>Přijímat veřejné REST požadavky (výchozí: %u)</translation> + </message> + <message> + <source>Activating best chain...</source> + <translation>Aktivuji nejlepší řetězec...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>V prořezávacím režimu se s pěněženkou nemůžu spustit.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Nemohu přeložit -whitebind adresu: '%s'</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Zvolit adresář pro data při startu (výchozí: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Připojit se přes SOCKS5 proxy</translation> </message> @@ -3139,6 +3209,10 @@ Adresa: %4 <translation>Selhala úvodní zevrubná prověrka. Bitcoin Core se ukončuje.</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Neplatná částka pro -maxtxfee=<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Neplatná částka pro -minrelaytxfee=<částka>: '%s'</translation> </message> @@ -3175,12 +3249,16 @@ Adresa: %4 <translation>Možnosti RPC serveru:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Náhodně zahazovat jednu z každých <n> síťových zpráv</translation> + <source>RPC support for HTTP persistent connections (default: %d)</source> + <translation>Podpora RPC pro perzistentní HTTP spojení (výchozí: %d)</translation> + </message> + <message> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Při startu znovu vytvořit index řetězce bloků z aktuálních blk000??.dat souborů</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Náhodně pozměňovat jednu z každých <n> síťových zpráv</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Přijímat a zobrazovat poplachy z P2P sítě (výchozí: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3191,10 +3269,22 @@ Adresa: %4 <translation>Posílat transakce pokud možno bez poplatků (výchozí: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Nastavit kořenové SSL certifikáty pro platební požadavky (výchozí: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Nastavit jazyk, například „de_DE“ (výchozí: systémové nastavení)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Zobrazit všechny možnosti ladění (užití: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Zobrazit startovací obrazovku (výchozí: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Při spuštění klienta zmenšit soubor debug.log (výchozí: 1, pokud není zadáno -debug)</translation> </message> @@ -3203,6 +3293,14 @@ Adresa: %4 <translation>Nepodařilo se podepsat transakci</translation> </message> <message> + <source>Start minimized</source> + <translation>Nastartovat minimalizovaně</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Částka v transakci je příliš malá na pokrytí poplatku</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Tohle je experimentální program.</translation> </message> @@ -3223,6 +3321,10 @@ Adresa: %4 <translation>Transakce je příliš velká</translation> </message> <message> + <source>UI Options:</source> + <translation>Možnosti UI:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Nedaří se mi připojit na %s na tomhle počítači (operace bind vrátila chybu %s)</translation> </message> @@ -3243,10 +3345,6 @@ Adresa: %4 <translation>Upozornění</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Upozornění: tahle verze je zastaralá, měl bys ji aktualizovat!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Upozornění: Nepodporovaný argument -benchmark se ignoruje, použij -debug=bench.</translation> </message> @@ -3307,18 +3405,10 @@ Adresa: %4 <translation>(1 = ukládat transakční metadata, např. majitele účtu a informace o platebním požadavku, 2 = mazat transakční metadata)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Promítnout databázovou aktivitu z paměťového prostoru do záznamu na disku každých <n> megabajtů (výchozí: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Jak moc důkladná má být verifikace bloků -checkblocks (0-4, výchozí: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Zaznamenávat během těžení bloků prioritu transakce a poplatek za kB (výchozí: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Spravovat úplný index transakcí, který je využíván rpc voláním getrawtransaction (výchozí: %u)</translation> </message> @@ -3347,18 +3437,10 @@ Adresa: %4 <translation>Vždy získávat adresy dalších protějšků přes DNS (výchozí: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Vypnout bezpečný režim (safemode), překrýt skutečnou událost bezpečného režimu (výchozí: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Chyba při načítání wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Vynutit bezpečný mód (výchozí: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Těžit (výchozí: %u)</translation> </message> @@ -3375,10 +3457,6 @@ Adresa: %4 <translation>Neplatná -proxy adresa: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Omezit velikost vyrovnávací paměti pro podpisy na <n> položek (výchozí: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Čekat na JSON-RPC spojení na <portu> (výchozí: %u nebo testnet: %u)</translation> </message> @@ -3391,6 +3469,10 @@ Adresa: %4 <translation>Povolit nejvýše <n> protějšků (výchozí: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Transakce z peněženky rozesílat</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Maximální velikost přijímacího bufferu pro každé spojení, <n>*1000 bajtů (výchozí: %u)</translation> </message> @@ -3399,10 +3481,6 @@ Adresa: %4 <translation>Maximální velikost odesílacího bufferu pro každé spojení, <n>*1000 bajtů (výchozí: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Uznávat pouze řetězec bloků, který odpovídá vnitřním kontrolním bodům (výchozí: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Připojit před ladicí výstup časové razítko (výchozí: %u)</translation> </message> @@ -3415,10 +3493,6 @@ Adresa: %4 <translation>Přeposílat ne-P2SH multisig (výchozí: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Spustit vlákno pročišťující periodicky peněženku (výchozí: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Soubor se serverovým certifikátem (výchozí: %s)</translation> </message> @@ -3439,10 +3513,6 @@ Adresa: %4 <translation>Nastavení počtu vláken pro servisní RPC volání (výchozí: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Nastavit příznak DB_PRIVATE v databázovém prostředí peněženky (výchozí: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Konfigurační soubor (výchozí: %s)</translation> </message> @@ -3455,10 +3525,6 @@ Adresa: %4 <translation>Utrácet i ještě nepotvrzené drobné při posílání transakcí (výchozí: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Ukončit se po importu bloků z disku (výchozí: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Práh pro odpojování zlobivých protějšků (výchozí: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_cy.ts b/src/qt/locale/bitcoin_cy.ts index c9c4379248..1b8eb3dc41 100644 --- a/src/qt/locale/bitcoin_cy.ts +++ b/src/qt/locale/bitcoin_cy.ts @@ -1,4 +1,4 @@ -<TS language="cy" version="2.1"> +<TS language="cy" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -68,10 +68,6 @@ <translation>Newid cyfrinymadrodd</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Teipiwch yr hen cyfrinymadrodd a chyfrinymadrodd newydd i mewn i'r waled.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Cadarnau amgryptiad y waled</translation> </message> @@ -441,13 +437,13 @@ <translation>Math</translation> </message> <message> - <source>Address</source> - <translation>Cyfeiriad</translation> - </message> - <message> <source>Open until %1</source> <translation>Agor tan %1</translation> </message> + <message> + <source>Label</source> + <translation>Label</translation> + </message> </context> <context> <name>TransactionView</name> diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index a5113d4a55..60b8925e8c 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -1,4 +1,4 @@ -<TS language="da" version="2.1"> +<TS language="da" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ <translation>Skift adgangskode</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Indtast den gamle og den nye adgangskode til tegnebogen.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Bekræft tegnebogskryptering</translation> </message> @@ -172,6 +168,10 @@ <translation>Er du sikker på, at du ønsker at kryptere din tegnebog?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -188,8 +188,8 @@ <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin vil nu lukke for at gennemføre krypteringsprocessen. Husk på, at kryptering af din tegnebog vil ikke beskytte dine bitcoins fuldt ud mod at blive stjålet af malware på din computer.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Indtast den gamle adgangskode og en ny adgangskode til tegnebogen.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>Send bitcoins til en Bitcoin-adresse</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Redigér konfigurationsindstillinger for Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Lav sikkerhedskopi af tegnebogen til et andet sted</translation> </message> @@ -403,6 +399,10 @@ <translation>&Om Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Ændr opsætning af Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Vis listen over brugte afsendelsesadresser og -mærkater</translation> </message> @@ -431,6 +431,10 @@ <translation>Ingen blokkilde tilgængelig …</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Bearbejdede %n blok med transaktionshistorik.</numerusform><numerusform>Bearbejdede %n blokke med transaktionshistorik.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n time</numerusform><numerusform>%n timer</numerusform></translation> </message> @@ -478,35 +482,49 @@ <source>Up to date</source> <translation>Opdateret</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>%n blok af transaktionshistorikken er blevet behandlet.</numerusform><numerusform>%n blokke af transaktionshistorikken er blevet behandlet.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Indhenter …</translation> </message> <message> - <source>Sent transaction</source> - <translation>Afsendt transaktion</translation> + <source>Date: %1 +</source> + <translation>Dato: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Indgående transaktion</translation> + <source>Amount: %1 +</source> + <translation>Beløb: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Dato: %1 -Beløb: %2 -Type: %3 -Adresse: %4 + <translation>Type: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Mærkat: %1 </translation> </message> <message> + <source>Address: %1 +</source> + <translation>Adresse: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Afsendt transaktion</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Indgående transaktion</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Tegnebog er <b>krypteret</b> og i øjeblikket <b>ulåst</b></translation> </message> @@ -697,6 +715,18 @@ Adresse: %4 <translation>ingen</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Denne mærkat bliver rød, hvis transaktionsstørrelsen er større end 1000 byte.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Denne mærkat bliver rød, hvis prioriteten er mindre end "medium".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Denne mærkat bliver rød, hvis en eller flere modtagere modtager et beløb, der er mindre end %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Kan variere med +/- %1 satoshi per input.</translation> </message> @@ -709,10 +739,6 @@ Adresse: %4 <translation>nej</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Dette mærkat bliver rødt, hvis transaktionsstørrelsen er større end 1000 byte.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Dette betyder, at et gebyr på mindst %1 pr. kB er nødvendigt.</translation> </message> @@ -725,14 +751,6 @@ Adresse: %4 <translation>Transaktioner med højere prioritet har højere sansynlighed for at blive inkluderet i en blok.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Dette mærkat bliver rødt, hvis prioriteten er mindre end "medium".</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Dette mærkat bliver rødt, hvis mindst én modtager et beløb mindre end %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(ingen mærkat)</translation> </message> @@ -853,30 +871,6 @@ Adresse: %4 <source>command-line options</source> <translation>kommandolinjetilvalg</translation> </message> - <message> - <source>UI options</source> - <translation>Brugergrænsefladeindstillinger</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Angiv sprog, fx "da_DK" (standard: systemlokalitet)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Start minimeret</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Sæt SSL-rodcertifikater for betalingsanmodning (standard: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Vis opstartsbillede ved opstart (standard: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Vælg datamappe ved opstart (standard: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -955,14 +949,6 @@ Adresse: %4 <translation>&Generelt</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Start Bitcoin automatisk, når der logges ind på systemet.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Start Bitcoin ved systemlogin</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Størrelsen på &databasens cache</translation> </message> @@ -987,6 +973,14 @@ Adresse: %4 <translation>IP-adresse for proxyen (fx IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Sproget for brugerfladen kan vælges her. Denne indstilling vil træde i kraft efter genstart af Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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 |.</translation> </message> @@ -1011,6 +1005,14 @@ Adresse: %4 <translation>&Netværk</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Start Bitcoin Core automatisk efter der logges ind på systemet.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Start Bitcoin Core ved system-login</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = efterlad så mange kerner fri)</translation> </message> @@ -1075,10 +1077,6 @@ Adresse: %4 <translation>&Minimér til statusfeltet i stedet for proceslinjen</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimér i stedet for at afslutte programmet, når vinduet lukkes. Når denne indstilling er valgt, vil programmet kun blive lukket, når du har valgt Afslut i menuen.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimér ved lukning</translation> </message> @@ -1091,10 +1089,6 @@ Adresse: %4 <translation>&Sprog for brugergrænseflade:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Sproget for brugergrænsefladen kan angives her. Denne indstilling træder først i kraft, når Bitcoin genstartes.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Enhed at vise beløb i:</translation> </message> @@ -1131,8 +1125,8 @@ Adresse: %4 <translation>Genstart af klienten er nødvendig for at aktivere ændringer.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Klienten vil blive lukket ned; vil du fortsætte?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Klienten vil lukke ned. Vil du fortsætte?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1217,10 +1211,6 @@ Adresse: %4 <source>Current total balance in watch-only addresses</source> <translation>Nuværende totalsaldo på kigge-adresser</translation> </message> - <message> - <source>out of sync</source> - <translation>ikke synkroniseret</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1241,10 +1231,6 @@ Adresse: %4 <translation>Netværk for betalingsanmodning stemmer ikke overens med klientens netværk.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Betalingsanmodning er udløbet.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Betalingsanmodning er ikke klargjort.</translation> </message> @@ -1277,10 +1263,18 @@ Adresse: %4 <translation>Fil for betalingsanmodning kan ikke læses! Dette kan skyldes en ugyldig fil for betalingsanmodning.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Betalingsanmodning er udløbet.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Ikke-verificerede betalingsanmodninger for tilpassede betalings-scripts understøttes ikke.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Ugyldig betalingsanmodning.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Tilbagebetaling fra %1</translation> </message> @@ -1320,8 +1314,8 @@ Adresse: %4 <translation>Brugeragent</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Adresse/værtsnavn</translation> + <source>Node/Service</source> + <translation>Knude/tjeneste</translation> </message> <message> <source>Ping Time</source> @@ -1355,14 +1349,6 @@ Adresse: %4 <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>NETVÆRK</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>UKENDT</translation> - </message> - <message> <source>None</source> <translation>Ingen</translation> </message> @@ -1453,6 +1439,10 @@ Adresse: %4 <translation>Nuværende antal blokke</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Åbn Bitcoin Cores fejlsøgningslogfil fra den aktuelle datamappe. Dette kan tage nogle få sekunder for store logfiler.</translation> + </message> + <message> <source>Received</source> <translation>Modtaget</translation> </message> @@ -1521,6 +1511,10 @@ Adresse: %4 <translation>Ping-tid</translation> </message> <message> + <source>Time Offset</source> + <translation>Tidsforskydning</translation> + </message> + <message> <source>Last block time</source> <translation>Tidsstempel for seneste blok</translation> </message> @@ -1561,16 +1555,12 @@ Adresse: %4 <translation>Fejlsøgningslogfil</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Åbn Bitcoin-fejlsøgningslogfilen fra den nuværende datamappe. Dette kan tage nogle få sekunder for store logfiler.</translation> - </message> - <message> <source>Clear console</source> <translation>Ryd konsol</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Velkommen til Bitcoin RPC-konsollen.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Velkommen til Bitcoin Cores RPC-konsol.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1861,14 +1851,6 @@ Adresse: %4 <translation>sammenfold gebyropsætning</translation> </message> <message> - <source>Minimize</source> - <translation>Minimér</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Hvis det brugertilpassede gebyr er sat til 1000 satoshis, og transaktionen kun fylder 250 byte, betaler "pr. kilobyte" kun 250 satoshis i gebyr, mens "mindst" betaler 1000 satoshis. For transaktioner større end en kilobyte betaler begge pr. kilobyte.</translation> - </message> - <message> <source>per kilobyte</source> <translation>pr. kilobyte</translation> </message> @@ -1877,6 +1859,10 @@ Adresse: %4 <translation>Hvis det brugertilpassede gebyr er sat til 1000 satoshis, og transaktionen kun fylder 250 byte, betaler "pr. kilobyte" kun 250 satoshis i gebyr, mens "total mindst" betaler 1000 satoshis. For transaktioner større end en kilobyte betaler begge pr. kilobyte.</translation> </message> <message> + <source>Hide</source> + <translation>Skjul</translation> + </message> + <message> <source>total at least</source> <translation>total mindst</translation> </message> @@ -1997,10 +1983,6 @@ Adresse: %4 <translation>eller</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Modtagerens adresse er ikke gyldig. Tjek venligst adressen igen.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Beløbet til betaling skal være større end 0.</translation> </message> @@ -2013,10 +1995,6 @@ Adresse: %4 <translation>Totalen overstiger din saldo, når transaktionsgebyret på %1 er inkluderet.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Duplikeret adresse fundet. Du kan kun sende til hver adresse én gang pr. afsendelse.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Oprettelse af transaktion mislykkedes!</translation> </message> @@ -2025,16 +2003,28 @@ Adresse: %4 <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> - <translation>Et gebyr højere end %1 anses som et vanvittigt højt gebyr.</translation> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Et gebyr højere end %1 opfattes som et absurd højt gebyr.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Betalingsanmodning er udløbet.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Bekræftelse estimeres til at begynde inden for %n blok.</numerusform><numerusform>Bekræftelse estimeres til at begynde inden for %n blokke.</numerusform></translation> </message> <message> <source>Pay only the minimum fee of %1</source> <translation>Betal kun det minimale gebyr på %1</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Bekræftelse vurderes at begynde inden for %1 blok(ke).</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Modtageradressen er ikke gyldig. Tjek venligst igen.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Adressegenganger fundet. Adresser bør kun bruges én gang hver.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2108,12 +2098,24 @@ Adresse: %4 <translation>Fjern denne indgang</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>Gebyret vil blive trukket fra det sendte beløb. Modtageren vil modtage færre bitcoin, end du indtaster i beløbfeltet. Hvis flere modtagere vælges, vil gebyret deles ligeligt.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>&Træk gebyr fra beløb</translation> + </message> + <message> <source>Message:</source> <translation>Besked:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Dette er en verificeret betalingsanmodning.</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Dette er en uautentificeret betalingsanmodning.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Dette er en autentificeret betalingsanmodning.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2124,10 +2126,6 @@ Adresse: %4 <translation>En besked, som blev føjet til "bitcon:"-URI'en, som vil gemmes med transaktionen til din reference. Bemærk: Denne besked vil ikke blive sendt over Bitcoin-netværket.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Dette er en ikke-verificeret betalingsanmodning.</translation> - </message> - <message> <source>Pay To:</source> <translation>Betal til:</translation> </message> @@ -2158,8 +2156,8 @@ Adresse: %4 <translation>&Underskriv besked</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Du kan underskrive beskeder med dine Bitcoin-adresser for at bevise, at de tilhører dig. Pas på ikke at underskrive noget vagt, da phisingangreb kan narre dig til at overdrage din identitet. Underskriv kun fuldt detaljerede udsagn, du er enig i.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Du kan signere beskeder/aftaler med dine adresser for at bevise, at du kan modtage bitcoin, der bliver sendt til adresserne. Vær forsigtig med ikke at signere noget vagt eller tilfældigt, da eventuelle phishing-angreb kan snyde dig til at overlade din identitet til dem. Signér kun fuldt ud detaljerede udsagn, som du er enig i.</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2214,8 +2212,8 @@ Adresse: %4 <translation>&Verificér besked</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Indtast herunder den underskrivende adresse, beskeden (inkludér linjeskift, mellemrum mv. nøjagtigt, som de fremgår) og underskriften for at verificere beskeden. Vær forsigtig med ikke at lægge mere i underskriften end besked selv, så du undgår at blive narret af et man-in-the-middle-angreb.</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Indtast modtagerens adresse, besked (vær sikker på at kopiere linjeskift, mellemrum, tabuleringer, etc. præcist) og signatur herunder for at verificere beskeden. Vær forsigtig med ikke at læse noget ud fra signaturen, som ikke står i selve beskeden, for at undgå at blive snydt af et eventuelt man-in-the-middle-angreb. Bemærk, at dette kun beviser, at den signerende person kan modtage med adressen; det kan ikke bevise hvem der har sendt en given transaktion!</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2420,7 +2418,7 @@ Adresse: %4 </message> <message> <source>Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source> - <translation>Minede bitcoins skal modne %1 blokke, før de kan bruges. Da du genererede denne blok, blev den udsendt 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.</translation> + <translation>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.</translation> </message> <message> <source>Debug information</source> @@ -2481,10 +2479,6 @@ Adresse: %4 <translation>Type</translation> </message> <message> - <source>Address</source> - <translation>Adresse</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Umoden (%1 bekræftelser; vil være tilgængelig efter %2)</translation> </message> @@ -2513,6 +2507,10 @@ Adresse: %4 <translation>Offline</translation> </message> <message> + <source>Label</source> + <translation>Mærkat</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Ubekræftet</translation> </message> @@ -2569,8 +2567,8 @@ Adresse: %4 <translation>Afgør hvorvidt en kigge-adresse er involveret i denne transaktion.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Destinationsadresse for transaktion.</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Brugerdefineret hensigt/formål med transaktionen.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2823,16 +2821,16 @@ Adresse: %4 <translation>Distribueret under MIT-softwarelicensen; se den vedlagte fil COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Start regressionstesttilstand, som bruger en speciel kæde, hvor blokke kan løses med det samme.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Udfør kommando, når en transaktion i tegnebogen ændres (%s i kommandoen erstattes med TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>I denne tilstand styrer -genproclimit hvor mange blokke, der genereres med det samme.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Maksimalt totalt gebyr der kan bruges i en enkelt tegnebogstransaktion. For lav en værdi kan afbryde store transaktioner (standard: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Reducér pladskravene ved at beskære (slette, "prune") gamle blokke. Denne tilstand slår understøttelse af tegnebogen fra og er ikke kompatibel med -txindex. Advarsel: Fortrydelse af denne indstilling kræver download af hele blokkæden igen. (standard: 0 = slå beskæring af blokke fra, >%u = målstørrelse i MiB der skal bruges til blokfiler)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2847,6 +2845,14 @@ Adresse: %4 <translation>Ikke i stand til at tildele til %s på denne computer. Bitcoin Core kører sansynligvis allerede.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>ADVARSEL: unormalt mange blokke er genereret; %d blokke er modtaget i løbet af de seneste %d timer (%d forventet)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>ADVARSEL: tjek din netværksforbindelse; %d blokke er modtaget i løbet af de seneste %d timer (%d forventet)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Advarsel: -paytxfee er sat meget højt! Dette er det gebyr du vil betale, hvis du sender en transaktion.</translation> </message> @@ -2903,16 +2909,12 @@ Adresse: %4 <translation>Tilvalg for fejlfinding/test:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Find egen IP-adresse (standard: 1 når lytter og ingen -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Indlæs ikke tegnebogen og slå tegnebogs-RPC-kald fra</translation> </message> <message> <source>Do you want to rebuild the block database now?</source> - <translation>Ønsker du at genbygge blokdatabasen nu?</translation> + <translation>Ønsker du at genopbygge blokdatabasen nu?</translation> </message> <message> <source>Error initializing block database</source> @@ -2967,8 +2969,12 @@ Adresse: %4 <translation>Tilslut kun til knuder i netværk <net> (IPv4, IPv6 eller Onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Genbyg blokkædeindeks fra nuværende blk000??.dat filer</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>Beskæring kan ikke opsættes med en negativ værdi.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Beskæringstilstand er ikke kompatibel med -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2983,10 +2989,6 @@ Adresse: %4 <translation>Angiv tegnebogsfil (inden for datamappe)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>This is intended for regression testing tools and app development.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Brug UPnP til at konfigurere den lyttende port (standard: %u)</translation> </message> @@ -3007,6 +3009,10 @@ Adresse: %4 <translation>Tilvalg for tegnebog:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Advarsel: Denne version er forældet; opgradering påkrævet!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Du er nødt til at genopbygge databasen ved hjælp af -reindex for at ændre -txindex</translation> </message> @@ -3035,14 +3041,14 @@ Adresse: %4 <translation>Kan ikke opnå en lås på datamappe %s. Bitcoin Core kører sansynligvis allerede.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Rate-begræns kontinuerligt gratis transaktioner til <n>*1000 byte i minuttet (standard: %u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>Opret nye filer med systemstandard for rettigheder i stedet for umask 077 (kun virksomt med tegnebogsfunktionalitet slået fra)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Opdag egne IP-adresser (standard: 1 under lytning og ingen -externalip eller -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Fejl: Lytning efter indkommende forbindelser mislykkedes (lytning resultarede i fejl %s)</translation> </message> @@ -3059,10 +3065,6 @@ Adresse: %4 <translation>Gebyrer (i BTC/Kb) mindre end dette opfattes som nulgebyr for videresendelse (standard: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Gebyrer (i BTC/Kb) mindre end dette opfattes som nulgebyr for oprettelse af transaktion (standard: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Hvis paytxfee ikke er sat, inkluderes nok gebyr til at transaktioner begynder at blive bekræftet ingen for gennemsnitligt n blokke (standard: %u)</translation> </message> @@ -3075,16 +3077,16 @@ Adresse: %4 <translation>Maksimal størrelse på data i transaktioner til dataoverførsel, som vi videresender og miner (standard: %u)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>Maksimalt totalgebyr der bruges på en enkelt tegnebogstransaktion. Sættes det for lavt kan store transaktioner afbrydes (standard: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Beskæring opsat under minimumsværdien %d MB. Brug venligst en højere værdi.</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Forespørgsel</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>Kræv høj prioritet for at videresende transaktioner med intet eller lavt gebyr (standard: %u)</translation> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Brug tilfældige akkreditiver for hver proxy-forbindelse. Dette tillader strømisolation med Tor (standard: %u)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3095,6 +3097,10 @@ Adresse: %4 <translation>Sæt antaller af tråde for coin-generering, hvis aktiveret (-1 = alle kerner, standard: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Transaktionsbeløbet er for lille til at sende, når gebyret er trukket fra</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -3135,14 +3141,34 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>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</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Du er nødt til at genopbygge databasen ved hjælp af -reindex for at gå tilbage til ikke-beskåret tilstand. Dette vil downloade hele blokkæden igen</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(standard: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Acceptér offentlige REST-anmodninger (standard: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Aktiverer bedste kæde …</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Kan ikke køre med en tegnebog i beskåret tilstand.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Kan ikke løse -whitebind adresse: "%s"</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Vælg datamappe ved opstart (standard: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Forbind gennem SOCKS5-proxy</translation> </message> @@ -3223,12 +3249,12 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>RPC-understøttelse for HTTP-persistente forbindelser (standard: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Drop tilfældigt 1 ud af hver <n> netværksbeskeder</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Genopbyg blokkædeindeks fra nuværende blk000??.dat-filer ved opstart</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Slør tilfældigt 1 ud af hver <n> netværksbeskeder</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Modtag og vis P2P-netværksadvarsler (standard: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3239,10 +3265,22 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Send transaktioner som nul-gebyr-transaktioner hvis muligt (standard: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Sæt SSL-rodcertifikater for betalingsanmodning (standard: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Angiv sprog, fx "da_DK" (standard: systemlokalitet)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Vis alle tilvalg for fejlsøgning (brug: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Vis opstartsbillede ved opstart (standard: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Formindsk debug.log filen ved klientopstart (standard: 1 hvis ikke -debug)</translation> </message> @@ -3251,6 +3289,14 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Underskrift af transaktion mislykkedes</translation> </message> <message> + <source>Start minimized</source> + <translation>Start minimeret</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Transaktionsbeløbet er for lille til at betale gebyret</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Dette er eksperimentelt software.</translation> </message> @@ -3271,6 +3317,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transaktionen er for stor</translation> </message> <message> + <source>UI Options:</source> + <translation>Indstillinger for brugerflade:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Ikke i stand til at tildele til %s på denne computer (bind returnerede fejl %s)</translation> </message> @@ -3291,10 +3341,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Advarsel</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Advarsel: Denne version er forældet, opgradering påkrævet!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Advarsel: Ikke understøttet argument -benchmark ignoreret, brug -debug=bench.</translation> </message> @@ -3355,18 +3401,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = behold metadata for transaktion, fx kontoindehaver og information om betalingsanmodning, 2 = drop metadata for transaktion)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Flyt databaseaktivitet fra hukommelsespulje til disklog hver <n> megabyte (standard: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Hvor gennemarbejdet blokverificeringen for -checkblocks er (0-4; standard: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Prioritet for transaktionslog og gebyr pr. kB under udvinding af blokke (standard: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Vedligehold et komplet transaktionsindeks, der bruges af rpc-kaldet getrawtransaction (standard: %u)</translation> </message> @@ -3395,18 +3433,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Forespørg altid adresser på andre knuder via DNS-opslag (default: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Slå sikker tilstand fra, tilsidesæt hændelser fra sikker tilstand (standard: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Fejl ved indlæsning af wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Gennemtving sikker tilstand (standard: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Generér bitcoins (standard: %u)</translation> </message> @@ -3423,10 +3453,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ugyldig -proxy adresse: "%s"</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Begræns størrelsen på signaturcache til <n> indgange (standard: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Lyt efter JSON-RPC-forbindelser på <port> (standard: %u eller testnet: %u)</translation> </message> @@ -3439,6 +3465,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Oprethold højest <n> forbindelser til andre knuder (standard: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Få tegnebogen til at transmittere transaktioner</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Maksimum for modtagelsesbuffer pr. forbindelse, <n>*1000 byte (standard: %u)</translation> </message> @@ -3447,10 +3477,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Maksimum for afsendelsesbuffer pr. forbindelse, <n>*1000 byte (standard: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Acceptér kun indbyggede kontrolposter, der matcher blokkæden (standard: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Føj tidsstempel foran fejlsøgningsoutput (standard: %u)</translation> </message> @@ -3463,10 +3489,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Videresend ikke-P2SH multisig (standard: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Kør en tråd for periodisk at rydde tegnebog (standard: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Servercertifikat-fil (standard: %s) </translation> @@ -3489,10 +3511,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Angiv antallet af tråde til at håndtere RPC-kald (standard: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Sætter DB_PRIVATE-flaget i tegnebogens db-miljø (standard: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Angiv konfigurationsfil (standard: %s)</translation> </message> @@ -3509,10 +3527,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Brug ubekræftede byttepenge under afsendelse af transaktioner (standard: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Stop kørsel efter import af blokke fra disk (standard: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Grænse for afbrydelse af forbindelse til knuder, der opfører sig upassende (standard: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index fc18a235eb..a50a6e60cb 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -1,4 +1,4 @@ -<TS language="de" version="2.1"> +<TS language="de" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ <translation>Passphrase ändern</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Geben Sie die alte und neue Wallet-Passphrase ein.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Wallet-Verschlüsselung bestätigen</translation> </message> @@ -172,6 +168,10 @@ <translation>Sind Sie sich sicher, dass Sie Ihre Wallet verschlüsseln möchten?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -188,8 +188,8 @@ <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin 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.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Geben Sie die alte und neue Wallet-Passphrase ein.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>Bitcoins an eine Bitcoin-Adresse überweisen</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Die Konfiguration des Clients bearbeiten</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Eine Wallet-Sicherungskopie erstellen und abspeichern</translation> </message> @@ -403,6 +399,10 @@ <translation>&Über Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Konfiguration von Bitcoin Core bearbeiten</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Liste verwendeter Zahlungsadressen und Bezeichnungen anzeigen</translation> </message> @@ -431,6 +431,10 @@ <translation>Keine Blockquelle verfügbar...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>%n Block des Transaktionsverlaufs verarbeitet.</numerusform><numerusform>%n Blöcke des Transaktionsverlaufs verarbeitet.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n Stunde</numerusform><numerusform>%n Stunden</numerusform></translation> </message> @@ -478,15 +482,41 @@ <source>Up to date</source> <translation>Auf aktuellem Stand</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>%n Block des Transaktionsverlaufs verarbeitet.</numerusform><numerusform>%n Blöcke des Transaktionsverlaufs verarbeitet.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Hole auf...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Datum: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Betrag: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Typ: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Bezeichnung: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Adresse: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Gesendete Transaktion</translation> </message> @@ -495,17 +525,6 @@ <translation>Eingehende Transaktion</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Datum: %1 -Betrag: %2 -Typ: %3 -Adresse: %4</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Wallet ist <b>verschlüsselt</b> und aktuell <b>entsperrt</b></translation> </message> @@ -696,6 +715,18 @@ Adresse: %4</translation> <translation>keine</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Diese Bezeichnung wird rot, wenn die Transaktion größer als 1000 Byte ist.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Diese Bezeichnung wird rot, wenn die Priorität niedriger als "mittel" ist.</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Diese Bezeichnung wird rot, wenn irgendein Empfänger einen Betrag kleiner als %1 erhält.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Kann pro Eingabe um +/- %1 Satoshi(s) abweichen.</translation> </message> @@ -708,10 +739,6 @@ Adresse: %4</translation> <translation>nein</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Diese Bezeichnung wird rot, wenn die Transaktion größer als 1000 Byte ist.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Das bedeutet, dass eine Gebühr von mindestens %1 pro kB erforderlich ist.</translation> </message> @@ -724,14 +751,6 @@ Adresse: %4</translation> <translation>Transaktionen mit höherer Priorität haben eine größere Chance in einen Block aufgenommen zu werden.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Diese Bezeichnung wird rot, wenn die Priorität niedriger als "mittel" ist.</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Diese Bezeichnung wird rot, wenn irgendein Empfänger einen Betrag kleiner als %1 erhält.</translation> - </message> - <message> <source>(no label)</source> <translation>(keine Bezeichnung)</translation> </message> @@ -852,30 +871,6 @@ Adresse: %4</translation> <source>command-line options</source> <translation>Kommandozeilenoptionen</translation> </message> - <message> - <source>UI options</source> - <translation>UI-Optionen</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Sprache festlegen, z.B. "de_DE" (Standard: Systemstandard)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Minimiert starten</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>SSL-Wurzelzertifikate für Zahlungsanforderungen festlegen (Standard: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Startbildschirm beim Starten anzeigen (Standard: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Datenverzeichnis beim Starten auswählen (Standard: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -958,14 +953,6 @@ Adresse: %4</translation> <translation>&Allgemein</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Bitcoin nach der Anmeldung am System automatisch ausführen.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Starte Bitcoin nach Systemanmeldung</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Größe des &Datenbankcaches</translation> </message> @@ -990,6 +977,14 @@ Adresse: %4</translation> <translation>IP-Adresse des Proxies (z.B. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Legt die Sprache der Benutzeroberfläche fest. Diese Einstellung wird erst nach einem Neustart von Bitcoin Core aktiv.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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.</translation> </message> @@ -1014,6 +1009,14 @@ Adresse: %4</translation> <translation>&Netzwerk</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Bitcoin Core nach der Anmeldung am System automatisch starten.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Bitcoin Core nach Systemanmeldung starten</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = automatisch, <0 = so viele Kerne frei lassen)</translation> </message> @@ -1078,10 +1081,6 @@ Adresse: %4</translation> <translation>In den Infobereich anstatt in die Taskleiste &minimieren</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimiert die Anwendung anstatt sie zu beenden wenn das Fenster geschlossen wird. Wenn dies aktiviert ist, müssen Sie das Programm über "Beenden" im Menü schließen.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>Beim Schließen m&inimieren</translation> </message> @@ -1094,10 +1093,6 @@ Adresse: %4</translation> <translation>&Sprache der Benutzeroberfläche:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Legt die Sprache der Benutzeroberfläche fest. Diese Einstellung wird erst nach einem Neustart von Bitcoin aktiv.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Einheit der Beträge:</translation> </message> @@ -1134,8 +1129,8 @@ Adresse: %4</translation> <translation>Clientneustart nötig, um die Änderungen zu aktivieren.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Client wird beendet, wollen Sie fortfahren?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Client wird beendet. Möchten Sie den Vorgang fortsetzen?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1220,10 +1215,6 @@ Adresse: %4</translation> <source>Current total balance in watch-only addresses</source> <translation>Aktueller Gesamtbetrag in beobachteten Adressen aus obigen Kategorien</translation> </message> - <message> - <source>out of sync</source> - <translation>nicht synchron</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1244,10 +1235,6 @@ Adresse: %4</translation> <translation>Netzwerk der Zahlungsanforderung stimmt nicht mit dem Client-Netzwerk überein.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Zahlungsanforderung ist abgelaufen.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Zahlungsanforderung ist nicht initialisiert.</translation> </message> @@ -1280,10 +1267,18 @@ Adresse: %4</translation> <translation>Zahlungsanforderungsdatei kann nicht gelesen werden! Dies kann durch eine ungültige Zahlungsanforderungsdatei verursacht werden.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Zahlungsanforderung abgelaufen.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Unverifizierte Zahlungsanforderungen an benutzerdefinierte Zahlungsskripte werden nicht unterstützt.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Ungültige Zahlungsanforderung.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Rücküberweisung von %1</translation> </message> @@ -1323,8 +1318,8 @@ Adresse: %4</translation> <translation>User-Agent</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Adresse/Hostname</translation> + <source>Node/Service</source> + <translation>Knoten/Dienst</translation> </message> <message> <source>Ping Time</source> @@ -1358,14 +1353,6 @@ Adresse: %4</translation> <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>NETZWERK</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>UNBEKANNT</translation> - </message> - <message> <source>None</source> <translation>Keine</translation> </message> @@ -1456,6 +1443,10 @@ Adresse: %4</translation> <translation>Aktuelle Anzahl Blöcke</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Öffnet die "Bitcoin Core"-Debugprotokolldatei aus dem aktuellen Datenverzeichnis. Dies kann bei großen Protokolldateien einige Sekunden dauern.</translation> + </message> + <message> <source>Received</source> <translation>Empfangen</translation> </message> @@ -1524,6 +1515,10 @@ Adresse: %4</translation> <translation>Pingzeit</translation> </message> <message> + <source>Time Offset</source> + <translation>Zeitversatz</translation> + </message> + <message> <source>Last block time</source> <translation>Letzte Blockzeit</translation> </message> @@ -1564,16 +1559,12 @@ Adresse: %4</translation> <translation>Debugprotokolldatei</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Öffnet die Bitcoin-Debugprotokolldatei aus dem aktuellen Datenverzeichnis. Dies kann bei großen Protokolldateien einige Sekunden dauern.</translation> - </message> - <message> <source>Clear console</source> <translation>Konsole zurücksetzen</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Willkommen in der Bitcoin-RPC-Konsole.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Willkommen in der "Bitcoin Core"-RPC-Konsole.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1864,14 +1855,6 @@ Adresse: %4</translation> <translation>Transaktionsgebühreneinstellungen ausblenden</translation> </message> <message> - <source>Minimize</source> - <translation>Minimieren</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Wenn die benutzerdefinierte Gebühr 1000 Satoshis beträgt und die Transaktion nur 250 Byte groß ist, wird bei Auswahl von "pro Kilobyte" eine Gebühr in Höhe von 250 Satoshis, bei Auswahl von "Mindestbetrag" eine Gebühr in Höhe von 1000 Satoshis bezahlt. Bei Transaktionen die Größer als ein Kilobyte sind, werden bei beiden Optionen die Gebühren pro Kilobyte bezahlt.</translation> - </message> - <message> <source>per kilobyte</source> <translation>pro Kilobyte</translation> </message> @@ -1880,6 +1863,10 @@ Adresse: %4</translation> <translation>Wenn die benutzerdefinierte Gebühr 1000 Satoshis beträgt und die Transaktion nur 250 Byte groß ist, wird bei Auswahl von "pro Kilobyte" eine Gebühr in Höhe von 250 Satoshis, bei Auswahl von "Mindestbetrag" eine Gebühr in Höhe von 1000 Satoshis bezahlt. Bei Transaktionen die Größer als ein Kilobyte sind, werden bei beiden Optionen die Gebühren pro Kilobyte bezahlt.</translation> </message> <message> + <source>Hide</source> + <translation>Ausblenden</translation> + </message> + <message> <source>total at least</source> <translation>Mindestbetrag</translation> </message> @@ -2000,10 +1987,6 @@ Adresse: %4</translation> <translation>oder</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Die Zahlungsadresse ist ungültig, bitte nochmals überprüfen.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Der zu zahlende Betrag muss größer als 0 sein.</translation> </message> @@ -2016,10 +1999,6 @@ Adresse: %4</translation> <translation>Der angegebene Betrag übersteigt aufgrund der Transaktionsgebühr in Höhe von %1 Ihren Kontostand.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Doppelte Zahlungsadresse gefunden, pro Überweisung kann an jede Adresse nur einmalig etwas überwiesen werden.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Transaktionserstellung fehlgeschlagen!</translation> </message> @@ -2028,16 +2007,28 @@ Adresse: %4</translation> <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> + <source>A fee higher than %1 is considered an absurdly high fee.</source> <translation>Eine höhere Gebühr als %1 wird als unsinnig hohe Gebühr angesehen.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Zahlungsanforderung abgelaufen.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Voraussichtlicher Beginn der Bestätigung innerhalb von %n Block.</numerusform><numerusform>Voraussichtlicher Beginn der Bestätigung innerhalb von %n Blöcken.</numerusform></translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Nur die minimale Gebühr in Höhe von %1 zahlen</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Voraussichtlicher Beginn der Bestätigung innerhalb von %1 Blöcken.</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Die Zahlungsadresse ist ungültig, bitte nochmals überprüfen.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Doppelte Adresse entdeckt: Adressen dürfen jeweils nur einmal vorkommen.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2111,12 +2102,24 @@ Adresse: %4</translation> <translation>Diesen Eintrag entfernen</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>Die Gebühr wird vom zu überweisenden Betrag abgezogen. Der Empfänger wird also weniger Bitcoins erhalten, als Sie im Betrags-Feld eingegeben haben. Falls mehrere Empfänger ausgewählt wurden, wird die Gebühr gleichmäßig verteilt.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>Gebühr vom Betrag ab&ziehen</translation> + </message> + <message> <source>Message:</source> <translation>Nachricht:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Dies is eine verifizierte Zahlungsanforderung.</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Dies ist keine beglaubigte Zahlungsanforderung.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Dies ist eine beglaubigte Zahlungsanforderung.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2127,10 +2130,6 @@ Adresse: %4</translation> <translation>Eine an die "bitcoin:"-URI angefügte Nachricht, die zusammen mit der Transaktion gespeichert wird. Hinweis: Diese Nachricht wird nicht über das Bitcoin-Netzwerk gesendet.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Dies is eine unverifizierte Zahlungsanforderung.</translation> - </message> - <message> <source>Pay To:</source> <translation>Empfänger:</translation> </message> @@ -2161,8 +2160,8 @@ Adresse: %4</translation> <translation>Nachricht &signieren</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Sie können Nachrichten mit Ihren Adressen signieren, um den Besitz dieser Adressen zu beweisen. Bitte nutzen Sie diese Funktion mit Vorsicht und nehmen Sie sich vor Phishingangriffen in Acht. Signieren Sie nur Nachrichten, mit denen Sie vollständig einverstanden sind.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Sie können Nachrichten/Vereinbarungen mit Hilfe Ihrer Adressen signieren, um zu beweisen, dass Sie Bitcoins empfangen können, die an diese Adressen überwiesen werden. Seien Sie vorsichtig und signieren Sie nichts Vages oder Willkürliches, um Ihre Indentität vor Phishingangriffen zu schützen. Signieren Sie nur vollständig-detaillierte Aussagen, mit denen Sie auch einverstanden sind.</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2217,8 +2216,8 @@ Adresse: %4</translation> <translation>Nachricht &verifizieren</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Geben Sie die signierende Adresse, Nachricht (achten Sie darauf Zeilenumbrüche, Leerzeichen, Tabulatoren usw. exakt zu kopieren) und Signatur unten ein, um die Nachricht zu verifizieren. Vorsicht, interpretieren Sie nicht mehr in die Signatur hinein, als in der signierten Nachricht selber enthalten ist, um nicht von einem Man-in-the-middle-Angriff hinters Licht geführt zu werden.</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Geben Sie die Zahlungsadresse des Empfängers, Nachricht (achten Sie darauf Zeilenumbrüche, Leerzeichen, Tabulatoren usw. exakt zu kopieren) und Signatur unten ein, um die Nachricht zu verifizieren. Vorsicht, interpretieren Sie nicht mehr in die Signatur hinein, als in der signierten Nachricht selber enthalten ist, um nicht von einem Man-in-the-middle-Angriff hinters Licht geführt zu werden. Beachten Sie dass dies nur beweißt, dass die signierende Partei über diese Adresse Überweisungen empfangen kann.</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2484,10 +2483,6 @@ Adresse: %4</translation> <translation>Typ</translation> </message> <message> - <source>Address</source> - <translation>Adresse</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Unreif (%1 Bestätigungen, wird verfügbar sein nach %2)</translation> </message> @@ -2516,6 +2511,10 @@ Adresse: %4</translation> <translation>Offline</translation> </message> <message> + <source>Label</source> + <translation>Bezeichnung</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Unbestätigt</translation> </message> @@ -2572,8 +2571,8 @@ Adresse: %4</translation> <translation>Zeigt an, ob eine beobachtete Adresse in diese Transaktion involviert ist.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Zieladresse der Transaktion.</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Benutzerdefinierte Absicht bzw. Verwendungszweck der Transaktion</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2826,16 +2825,16 @@ Adresse: %4</translation> <translation>Veröffentlicht unter der MIT-Softwarelizenz, siehe beiligende Datei COPYING oder <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Regressionstest-Modus aktivieren, der eine spezielle Blockkette nutzt, in der Blöcke sofort gelöst werden können.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Befehl ausführen wenn sich eine Wallet-Transaktion verändert (%s im Befehl wird durch die Transaktions-ID ersetzt)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>In diesem Modus legt -genproclimit fest, wie viele Blöcke sofort erzeugt werden.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Maximale Gesamtgebühren je Wallet-Transaktion, ein zu niedriger Wert kann große Transaktionen abbrechen (Standard: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Speicherplatzanforderung durch kürzen (löschen) alter Blöcke reduzieren. Dieser Modus deaktiviert die Wallet-Unterstützung und ist nicht mit -txindex 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)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2850,6 +2849,14 @@ Adresse: %4</translation> <translation>Kann auf diesem Computer nicht an %s binden, da Bitcoin Core wahrscheinlich bereits gestartet wurde.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>Warnung: Es wurde eine ungewöhnlich hohe Anzahl Blöcke erzeugt, %d Blöcke wurden in den letzten %d Stunden empfangen (%d wurden erwartet).</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>Warnung: Überprüpfen Sie ihre Netzwerkverbindung, %d Blöcke wurden in den letzten %d Stunden empfangen (%d wurden erwartet).</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Warnung: -paytxfee ist auf einen sehr hohen Wert festgelegt! Dies ist die Gebühr die beim Senden einer Transaktion fällig wird.</translation> </message> @@ -2906,10 +2913,6 @@ Adresse: %4</translation> <translation>Debugging-/Testoptionen:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Eigene IP-Adresse erkennen (Standard: 1, wenn abgehört wird und nicht -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Die Wallet nicht laden und Wallet-RPC-Aufrufe deaktivieren</translation> </message> @@ -2970,8 +2973,12 @@ Adresse: %4</translation> <translation>Nur zu Knoten des Netzwerktyps <net> verbinden (ipv4, ipv6 oder onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Blockkettenindex aus aktuellen Dateien blk000??.dat wiederaufbauen</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>Kürzungsmodus kann nicht mit einem negativen Wert konfiguriert werden.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Kürzungsmodus ist nicht mit -txindex kompatibel.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2986,10 +2993,6 @@ Adresse: %4</translation> <translation>Wallet-Datei angeben (innerhalb des Datenverzeichnisses)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Dies ist für Regressionstest-Tools und Anwendungsentwicklung gedacht.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: %u)</translation> </message> @@ -3010,6 +3013,10 @@ Adresse: %4</translation> <translation>Wallet-Optionen:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Warnung: Diese Version is veraltet, Aktualisierung erforderlich!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Sie müssen die Datenbank mit Hilfe von -reindex neu aufbauen, um -txindex zu verändern</translation> </message> @@ -3038,14 +3045,14 @@ Adresse: %4</translation> <translation>Datenverzeichnis %s kann nicht gesperrt werden, da Bitcoin Core wahrscheinlich bereits gestartet wurde.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Anzahl der freien Transaktionen auf <n> * 1000 Byte pro Minute begrenzen (Standard: %u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>Neue Dateien mit Standard-Systemrechten erzeugen, anstatt mit umask 077 (nur mit deaktivierter Walletfunktion nutzbar)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Eigene IP-Adressen ermitteln (Standard: 1, wenn abgehört wird und nicht -externalip oder -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Fehler: Abhören nach eingehenden Verbindungen fehlgeschlagen (listen meldete Fehler %s)</translation> </message> @@ -3062,10 +3069,6 @@ Adresse: %4</translation> <translation>Niedrigere Gebühren (in BTC/Kb) als diese werden bei der Weiterleitung als gebührenfrei angesehen (Standard: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Niedrigere Gebühren (in BTC/Kb) als diese werden bei der Transaktionserstellung als gebührenfrei angesehen (Standard: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>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)</translation> </message> @@ -3078,16 +3081,16 @@ Adresse: %4</translation> <translation>Maximale Datengröße in "Data Carrier"-Transaktionen die weitergeleitet und erarbeitet werden (Standard: %u)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>Maximale Gesamtgebühren je Wallet-Transaktion, ein zu niedriger Wert kann große Transaktionen abbrechen (Standard: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Kürzungsmodus wurde kleiner als das Minimum in Höhe von %d MiB konfiguriert. Bitte verwenden Sie einen größeren Wert.</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Adressen von Gegenstellen via DNS-Namensauflösung finden, falls zu wenige Adressen verfügbar sind (Standard: 1, außer bei -connect)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>Zum Weiterleiten von freien Transaktionen oder Transaktionen mit niedrigen Gebühren eine hohe Priorität voraussetzen (Standard: %u)</translation> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Zufällige Anmeldedaten für jede Proxyverbindung verwenden. Dies aktiviert Tor-Datenflussisolation (Standard: %u)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3098,6 +3101,10 @@ Adresse: %4</translation> <translation>Maximale Anzahl an Threads zur Bitcoinerzeugung, wenn aktiviert, festlegen (-1 = alle Kerne, Standard: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Der Transaktionsbetrag ist zum senden zu niedrig, nachdem die Gebühr abgezogen wurde.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -3138,14 +3145,34 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>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.</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>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.</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(Standard: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Öffentliche REST-Anfragen annehmen (Standard: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Aktiviere beste Blockkette...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Eine Wallet kann im Kürzungsmodus nicht verwendet werden.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Kann Adresse in -whitebind nicht auflösen: '%s'</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Datenverzeichnis beim Starten auswählen (Standard: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Über einen SOCKS5-Proxy &verbinden</translation> </message> @@ -3226,12 +3253,12 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Unterstützung für persistente HTTP-Verbindungen bei RPC (Standard: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Zufällig eine von <n> Netzwerknachrichten verwerfen</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Blockkettenindex aus aktuellen Dateien blk000??.dat beim Starten wiederaufbauen</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Zufällig eine von <n> Netzwerknachrichten verwürfeln</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>P2P-Netzwerk-Alarme empfangen und anzeigen (Standard: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3242,10 +3269,22 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transaktionen, wenn möglich, als gebührenfreie Transaktion senden (Standard: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>SSL-Wurzelzertifikate für Zahlungsanforderungen festlegen (Standard: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Sprache festlegen, z.B. "de_DE" (Standard: Systemstandard)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Zeige alle Debuggingoptionen (Benutzung: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Startbildschirm beim Starten anzeigen (Standard: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Protokolldatei debug.log beim Starten des Clients kürzen (Standard: 1, wenn kein -debug)</translation> </message> @@ -3254,6 +3293,14 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Signierung der Transaktion fehlgeschlagen</translation> </message> <message> + <source>Start minimized</source> + <translation>Minimiert starten</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Der Transaktionsbetrag ist zu niedrig, um die Gebühr zu bezahlen.</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Dies ist experimentelle Software.</translation> </message> @@ -3274,6 +3321,10 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transaktion zu groß</translation> </message> <message> + <source>UI Options:</source> + <translation>Benutzeroberflächenoptionen:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Kann auf diesem Computer nicht an %s binden (bind meldete Fehler %s)</translation> </message> @@ -3294,10 +3345,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Warnung</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Warnung: Diese Version is veraltet, Aktualisierung erforderlich!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Warnung: Nicht unterstütztes Argument -benchmark wurde ignoriert, bitte -debug=bench verwenden.</translation> </message> @@ -3358,18 +3405,10 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = TX-Metadaten wie z.B. Accountbesitzer und Zahlungsanforderungsinformationen behalten, 2 = TX-Metadaten verwerfen)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Datenbankaktivitäten vom Arbeitsspeicher-Pool alle <n> Megabyte auf den Datenträger schreiben (Standard: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Legt fest, wie gründlich die Blockverifikation von -checkblocks ist (0-4, Standard: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Transaktionspriorität und Gebühr pro kB beim Erzeugen von Blöcken protokollieren (Standard: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Einen vollständigen Transaktionsindex führen, der vom RPC-Befehl "getrawtransaction" genutzt wird (Standard: %u)</translation> </message> @@ -3398,18 +3437,10 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Adressen von Gegenstellen immer über DNS-Namensauflösung abfragen (Standard: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Sicherheitsmodus deaktivieren, übergeht ein echtes Sicherheitsmodusereignis (Standard: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Fehler beim Laden von wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Sicherheitsmodus erzwingen (Standard: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Bitcoins erzeugen (Standard: %u)</translation> </message> @@ -3426,10 +3457,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ungültige Adresse in -proxy: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Größe des Signaturcaches auf <n> Einträge begrenzen (Standard: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation><port> nach JSON-RPC-Verbindungen abhören (Standard: %u oder Testnetz: %u)</translation> </message> @@ -3438,6 +3465,10 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Maximal <n> Verbindungen zu Gegenstellen aufrechterhalten (Standard: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Die Wallet soll Transaktionen übertragen/broadcasten</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Maximale Größe des Empfangspuffers pro Verbindung, <n> * 1000 Byte (Standard: %u)</translation> </message> @@ -3446,10 +3477,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Maximale Größe des Sendepuffers pro Verbindung, <n> * 1000 Byte (Standard: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Blockkette nur als gültig ansehen, wenn sie mit den integrierten Prüfpunkten übereinstimmt (Standard: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Debugausgaben einen Zeitstempel voranstellen (Standard: %u)</translation> </message> @@ -3462,10 +3489,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Nicht-"P2SH-Multisig" weiterleiten (Standard: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Einen Thread starten, der periodisch die Wallet sicher auf den Datenträger schreibt (Standard: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Serverzertifikat (Standard: %s)</translation> </message> @@ -3486,10 +3509,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Maximale Anzahl an Threads zur Verarbeitung von RPC-Anfragen festlegen (Standard: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>"DB_PRIVATE"-Flag in der Wallet-Datenbankumgebung setzen (Standard: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Konfigurationsdatei festlegen (Standard: %s)</translation> </message> @@ -3506,10 +3525,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Unbestätigtes Wechselgeld darf beim Senden von Transaktionen ausgegeben werden (Standard: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Beenden, nachdem Blöcke vom Datenträger importiert wurden (Standard: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Schwellenwert, um Verbindungen zu sich nicht konform verhaltenden Gegenstellen zu beenden (Standard: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts index 084c9fa753..8a0958a7bd 100644 --- a/src/qt/locale/bitcoin_el_GR.ts +++ b/src/qt/locale/bitcoin_el_GR.ts @@ -1,13 +1,17 @@ -<TS language="el_GR" version="2.1"> +<TS language="el_GR" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Δεξί-κλικ για επεξεργασία της διεύθυνσης ή της ετικέτας</translation> + </message> + <message> <source>Create a new address</source> <translation>Δημιουργία νέας διεύθυνσης</translation> </message> <message> <source>&New</source> - <translation>&Νέα</translation> + <translation>&Νέo</translation> </message> <message> <source>Copy the currently selected address to the system clipboard</source> @@ -87,7 +91,7 @@ </message> <message> <source>Exporting Failed</source> - <translation>Η εξαγωγή απέτυχε</translation> + <translation>Η Εξαγωγή Απέτυχε</translation> </message> <message> <source>There was an error trying to save the address list to %1. Please try again.</source> @@ -98,7 +102,7 @@ <name>AddressTableModel</name> <message> <source>Label</source> - <translation>Ετικέτα</translation> + <translation>Επιγραφή</translation> </message> <message> <source>Address</source> @@ -152,10 +156,6 @@ <translation>Άλλαξε κωδικο πρόσβασης</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Εισάγετε τον παλιό και τον νεο κωδικο στο πορτοφολι.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Επιβεβαίωσε την κρυπτογραφηση του πορτοφολιού</translation> </message> @@ -185,10 +185,6 @@ <translation>Εισάγετε τον νέο κωδικό πρόσβασης στον πορτοφόλι <br/> Παρακαλώ χρησιμοποιείστε ένα κωδικό με <b> 10 ή περισσότερους τυχαίους χαρακτήρες</b> ή <b> οχτώ ή παραπάνω λέξεις</b>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Το Bitcoin θα κλεισει τώρα για να τελειώσει την διαδικασία κρυπτογραφησης. Θυμησου ότι κρυπτογραφώντας το πορτοφολι σου δεν μπορείς να προστατέψεις πλήρως τα bitcoins σου από κλοπή στην περίπτωση όπου μολυνθεί ο υπολογιστής σου με κακόβουλο λογισμικό.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>Η κρυπτογραφηση του πορτοφολιού απέτυχε</translation> </message> @@ -308,10 +304,6 @@ <translation>Στείλε νομίσματα σε μια διεύθυνση bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Επεργασία ρυθμισεων επιλογών για το Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Δημιουργία αντιγράφου ασφαλείας πορτοφολιού σε άλλη τοποθεσία</translation> </message> @@ -419,34 +411,14 @@ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> <translation>Εμφανιση του Bitcoin-Qt μήνυματος βοήθειας για να πάρετε μια λίστα με τις πιθανές επιλογές Bitcoin γραμμής εντολών.</translation> </message> - <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n ενεργή σύνδεση στο δίκτυο Bitcoin</numerusform><numerusform>%n ενεργές συνδέσεις στο δίκτυο Βitcoin</numerusform></translation> - </message> <message> <source>No block source available...</source> <translation>Η πηγή του μπλοκ δεν ειναι διαθέσιμη... </translation> </message> - <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n ώρες </numerusform><numerusform>%n ώρες </numerusform></translation> - </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n ημέρες </numerusform><numerusform>%n ημέρες </numerusform></translation> - </message> - <message numerus="yes"> - <source>%n week(s)</source> - <translation><numerusform>%n εβδομαδες</numerusform><numerusform>%n εβδομαδες</numerusform></translation> - </message> <message> <source>%1 and %2</source> <translation>%1 και %2</translation> </message> - <message numerus="yes"> - <source>%n year(s)</source> - <translation><numerusform>%n έτος</numerusform><numerusform>%n έτη</numerusform></translation> - </message> <message> <source>%1 behind</source> <translation>%1 πίσω</translation> @@ -488,18 +460,6 @@ <translation>Εισερχόμενη συναλλαγή</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Ημερομηνία: %1 -Ποσό: %2 -Τύπος: %3 -Διεύθυνση: %4 -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Το πορτοφόλι είναι <b>κρυπτογραφημένο</b> και <b>ξεκλείδωτο</b></translation> </message> @@ -627,7 +587,7 @@ Address: %4 </message> <message> <source>Copy after fee</source> - <translation>Αντιγραφή ταρίφας</translation> + <translation>Αντιγραφή μετα-ταρίφας</translation> </message> <message> <source>Copy bytes</source> @@ -698,10 +658,6 @@ Address: %4 <translation>όχι</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Η ετικετα γινετε κοκκινη , αν το μεγεθος της συναλαγης ειναι μεγαλητερο απο 1000 bytes.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Ελάχιστο χρεώσιμο ποσό τουλάχιστο %1 ανα kB</translation> </message> @@ -710,14 +666,6 @@ Address: %4 <translation>Συναλλαγές με υψηλότερη προτεραιότητα είναι πιο πιθανό να περιλαμβάνονται σε ένα μπλοκ.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Η ετικέτα γίνεται κόκκινη , αν το μέγεθος της συναλαγής είναι μεγαλύτερο απο το ",μεσαίο",</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Η ετικέτα γίνεται κόκκινη , αν ο παραλήπτης παραλάβει ένα ποσό μικρότερο απο %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(χωρίς ετικέτα)</translation> </message> @@ -839,30 +787,6 @@ Address: %4 <source>command-line options</source> <translation>επιλογής γραμμής εντολών</translation> </message> - <message> - <source>UI options</source> - <translation>επιλογές UI</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Όρισε γλώσσα, για παράδειγμα "de_DE"(προεπιλογή:τοπικές ρυθμίσεις)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Έναρξη ελαχιστοποιημένο</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Ορίστε SSL root certificates για αίτηση πληρωμής (default: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Εμφάνισε την οθόνη εκκίνησης κατά την εκκίνηση(προεπιλογή:1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Επιλογή καταλόγου</translation> - </message> </context> <context> <name>Intro</name> @@ -937,14 +861,6 @@ Address: %4 <translation>&Κύριο</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Αυτόματη εκκίνηση του Bitcoin μετά την εισαγωγή στο σύστημα</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Έναρξη του Βιtcoin κατά την εκκίνηση του συστήματος</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Μέγεθος κρυφής μνήμης βάσης δεδομένων.</translation> </message> @@ -969,10 +885,18 @@ Address: %4 <translation>Διεύθυνση IP του διαμεσολαβητή (π.χ. 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> + <translation>URLs από τρίτους (π.χ. ένας εξερευνητής μπλοκ) τα οποία εμφανίζονται στην καρτέλα συναλλαγών ως στοιχεία μενού. Το %s στα URL αντικαθιστάται από την τιμή της κατατεμαχισμένης συναλλαγής.</translation> + </message> + <message> <source>Third party transaction URLs</source> <translation>Διευθύνσεις τρίτων συναλλαγών.</translation> </message> <message> + <source>Active command-line options that override above options:</source> + <translation>Ενεργές επιλογές γραμμής-εντολών που παρακάμπτουν τις παραπάνω επιλογές:</translation> + </message> + <message> <source>Reset all client options to default.</source> <translation>Επαναφορα όλων των επιλογων του πελάτη σε default.</translation> </message> @@ -985,6 +909,10 @@ Address: %4 <translation>&Δίκτυο</translation> </message> <message> + <source>(0 = auto, <0 = leave that many cores free)</source> + <translation>(0 = αυτόματο, <0 = ελεύθεροι πυρήνες)</translation> + </message> + <message> <source>W&allet</source> <translation>Π&ορτοφόλι</translation> </message> @@ -997,6 +925,14 @@ Address: %4 <translation>Επιλογή κατα πόσο να αναδείχνονται οι δυνατότητες ελέγχου κερμάτων.</translation> </message> <message> + <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source> + <translation>Εάν απενεργοποιήσετε το ξόδεμα μη επικυρωμένων ρέστων, τα ρέστα από μια συναλλαγή δεν μπορούν να χρησιμοποιηθούν έως ότου αυτή η συναλλαγή έχει έστω μια επικύρωση. Αυτό επίσης επηρεάζει το πως υπολογίζεται το υπόλοιπό σας.</translation> + </message> + <message> + <source>&Spend unconfirmed change</source> + <translation>&Ξόδεμα μη επικυρωμένων ρέστων</translation> + </message> + <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> <translation>Αυτόματο άνοιγμα των θυρών Bitcoin στον δρομολογητή. Λειτουργεί μόνο αν ο δρομολογητής σας υποστηρίζει τη λειτουργία UPnP.</translation> </message> @@ -1037,10 +973,6 @@ Address: %4 <translation>&Ελαχιστοποίηση στην περιοχή ειδοποιήσεων αντί της γραμμής εργασιών</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Ελαχιστοποίηση αντί για έξοδο κατά το κλείσιμο του παραθύρου</translation> - </message> - <message> <source>M&inimize on close</source> <translation>Ε&λαχιστοποίηση κατά το κλείσιμο</translation> </message> @@ -1053,10 +985,6 @@ Address: %4 <translation>Γλώσσα περιβάλλοντος εργασίας: </translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Εδώ μπορεί να ρυθμιστεί η γλώσσα διεπαφής χρήστη. Αυτή η ρύθμιση θα ισχύσει μετά την επανεκκίνηση του Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Μονάδα μέτρησης:</translation> </message> @@ -1066,7 +994,8 @@ Address: %4 </message> <message> <source>Whether to show coin control features or not.</source> - <translation>Επιλογή κατα πόσο να αναδείχνονται οι δυνατότητες ελέγχου κερμάτων.</translation> + <translation>Επιλογή κατα πόσο να αναδείχνονται οι δυνατότητες ελέγχου κερμάτων. +</translation> </message> <message> <source>&OK</source> @@ -1093,10 +1022,6 @@ Address: %4 <translation>Χρειάζεται επανεκκίνηση του προγράμματος για να ενεργοποιηθούν οι αλλαγές.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Η εφαρμογή θα τερματιστεί. Θέλετε να προχωρήσετε;</translation> - </message> - <message> <source>This change would require a client restart.</source> <translation>Η αλλαγή αυτή θα χρειαστεί επανεκκίνηση του προγράμματος</translation> </message> @@ -1156,6 +1081,10 @@ Address: %4 <translation>Το τρέχον συνολικό υπόλοιπο</translation> </message> <message> + <source>Your current balance in watch-only addresses</source> + <translation>Το τρέχον υπόλοιπο σας σε διευθύνσεις παρακολούθησης μόνο</translation> + </message> + <message> <source>Spendable:</source> <translation>Ξοδεμένα:</translation> </message> @@ -1164,8 +1093,16 @@ Address: %4 <translation>Πρόσφατες συναλλαγές</translation> </message> <message> - <source>out of sync</source> - <translation>εκτός συγχρονισμού</translation> + <source>Unconfirmed transactions to watch-only addresses</source> + <translation>Μη επικυρωμένες συναλλαγές σε διευθύνσεις παρακολούθησης μόνο</translation> + </message> + <message> + <source>Mined balance in watch-only addresses that has not yet matured</source> + <translation>Εξορυγμένο υπόλοιπο σε διευθύνσεις παρακολούθησης μόνο που δεν έχει ωριμάσει ακόμα</translation> + </message> + <message> + <source>Current total balance in watch-only addresses</source> + <translation>Το τρέχον συνολικό υπόλοιπο σε διευθύνσεις παρακολούθησης μόνο</translation> </message> </context> <context> @@ -1183,14 +1120,14 @@ Address: %4 <translation>Η αίτηση πληρωμής έχει αρνηθεί.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Η αίτηση πληρωμής έχει λήξει.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Η αίτηση πληρωμής δεν έχει αρχίζει ακόμα.</translation> </message> <message> + <source>Requested payment amount of %1 is too small (considered dust).</source> + <translation>Το ζητούμενο ποσό πληρωμής του %1 είναι πολύ μικρό (θεωρείται σκόνη)</translation> + </message> + <message> <source>Payment request error</source> <translation>Σφάλμα αιτήματος πληρωμής</translation> </message> @@ -1211,6 +1148,18 @@ Address: %4 <translation>Επιστροφή ποσού από %1</translation> </message> <message> + <source>Error communicating with %1: %2</source> + <translation>Σφάλμα επικοινωνίας με %1: %2</translation> + </message> + <message> + <source>Payment request cannot be parsed!</source> + <translation>Η αίτηση πληρωμής δεν μπορεί να αναλυθεί!</translation> + </message> + <message> + <source>Bad response from server %1</source> + <translation>Κακή απάντηση από διακομιστή %1</translation> + </message> + <message> <source>Payment acknowledged</source> <translation>Πληρωμή αναγνωρίστηκε</translation> </message> @@ -1222,10 +1171,6 @@ Address: %4 <context> <name>PeerTableModel</name> <message> - <source>Address/Hostname</source> - <translation>Διεύθυθνση/Όνομα υπολογιστή</translation> - </message> - <message> <source>Ping Time</source> <translation>Χρόνος καθυστέρησης</translation> </message> @@ -1257,14 +1202,6 @@ Address: %4 <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>Δίκτυο</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>Άγνωστο(α)</translation> - </message> - <message> <source>None</source> <translation>Κανένα</translation> </message> @@ -1327,6 +1264,10 @@ Address: %4 <translation>Χρησιμοποιηση της OpenSSL εκδοσης</translation> </message> <message> + <source>Using BerkeleyDB version</source> + <translation>Χρήση BerkeleyDB έκδοσης</translation> + </message> + <message> <source>Startup time</source> <translation>Χρόνος εκκίνησης</translation> </message> @@ -1355,6 +1296,18 @@ Address: %4 <translation>Παραλήφθησαν</translation> </message> <message> + <source>Sent</source> + <translation>Αποστολή</translation> + </message> + <message> + <source>&Peers</source> + <translation>&Χρήστες</translation> + </message> + <message> + <source>Select a peer to view detailed information.</source> + <translation>Επιλέξτε ένα χρήστη για να δείτε αναλυτικές πληροφορίες.</translation> + </message> + <message> <source>Version</source> <translation>Έκδοση</translation> </message> @@ -1363,6 +1316,38 @@ Address: %4 <translation>Υπηρεσίες</translation> </message> <message> + <source>Starting Height</source> + <translation>Αρχικό ύψος</translation> + </message> + <message> + <source>Sync Height</source> + <translation>Ύψος συγχονισμού</translation> + </message> + <message> + <source>Ban Score</source> + <translation>Σκορ αποκλησμού</translation> + </message> + <message> + <source>Connection Time</source> + <translation>Χρόνος σύνδεσης</translation> + </message> + <message> + <source>Last Send</source> + <translation>Τελευταία αποστολή</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Τελευταία λήψη</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Σταλθέντα bytes</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Ληφθέντα bytes</translation> + </message> + <message> <source>Ping Time</source> <translation>Χρόνος καθυστέρησης</translation> </message> @@ -1407,18 +1392,10 @@ Address: %4 <translation>Αρχείο καταγραφής εντοπισμού σφαλμάτων </translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Ανοίξτε το αρχείο καταγραφής εντοπισμού σφαλμάτων από τον τρέχοντα κατάλογο δεδομένων. Αυτό μπορεί να πάρει μερικά δευτερόλεπτα για τα μεγάλα αρχεία καταγραφής. </translation> - </message> - <message> <source>Clear console</source> <translation>Καθαρισμός κονσόλας</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Καλώς ήρθατε στην Bitcoin RPC κονσόλα.</translation> - </message> - <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Χρησιμοποιήστε το πάνω και κάτω βέλος για να περιηγηθείτε στο ιστορικο, και <b>Ctrl-L</b> για εκκαθαριση οθονης.</translation> </message> @@ -1462,7 +1439,11 @@ Address: %4 <source>Unknown</source> <translation>Άγνωστο(α)</translation> </message> - </context> + <message> + <source>Fetching...</source> + <translation>Ανάκτηση...</translation> + </message> +</context> <context> <name>ReceiveCoinsDialog</name> <message> @@ -1478,6 +1459,10 @@ Address: %4 <translation>&Μήνυμα:</translation> </message> <message> + <source>R&euse an existing receiving address (not recommended)</source> + <translation>Ε&παναχρησιμοποίηση υπάρχουσας διεύθυνσης λήψης (δεν συνιστάται)</translation> + </message> + <message> <source>Clear all fields of the form.</source> <translation>Καθαρισμός όλων των πεδίων της φόρμας.</translation> </message> @@ -1494,6 +1479,10 @@ Address: %4 <translation>Εμφάνιση</translation> </message> <message> + <source>Remove the selected entries from the list</source> + <translation>Αφαίρεση επιλεγμένων καταχωρίσεων από τη λίστα</translation> + </message> + <message> <source>Remove</source> <translation>Αφαίρεση</translation> </message> @@ -1521,10 +1510,18 @@ Address: %4 <translation>Αντιγραφη της επιλεγμενης διεύθυνσης στο πρόχειρο του συστηματος</translation> </message> <message> + <source>Copy &Address</source> + <translation>Αντιγραφή &Διεύθυνσης</translation> + </message> + <message> <source>&Save Image...</source> <translation>&Αποθήκευση εικόνας...</translation> </message> <message> + <source>Request payment to %1</source> + <translation>Αίτηση πληρωμής για %1</translation> + </message> + <message> <source>Payment information</source> <translation>Πληροφορίες πληρωμής</translation> </message> @@ -1542,7 +1539,7 @@ Address: %4 </message> <message> <source>Label</source> - <translation>Ετικέτα</translation> + <translation>Επιγραφή</translation> </message> <message> <source>Message</source> @@ -1565,7 +1562,7 @@ Address: %4 </message> <message> <source>Label</source> - <translation>Ετικέτα</translation> + <translation>Επιγραφή</translation> </message> <message> <source>Message</source> @@ -1599,6 +1596,10 @@ Address: %4 <translation>Χαρακτηρηστικά επιλογής κερμάτων</translation> </message> <message> + <source>Inputs...</source> + <translation>Εισροές...</translation> + </message> + <message> <source>automatically selected</source> <translation>επιλεγμένο αυτόματα</translation> </message> @@ -1635,6 +1636,14 @@ Address: %4 <translation>Ρέστα:</translation> </message> <message> + <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source> + <translation>Όταν ενεργό, αλλά η διεύθυνση ρέστων είναι κενή ή άκυρη, τα ρέστα θα σταλούν σε μία πρόσφατα δημιουργημένη διεύθυνση.</translation> + </message> + <message> + <source>Custom change address</source> + <translation>Προσαρμοσμένη διεύθυνση ρέστων</translation> + </message> + <message> <source>Transaction Fee:</source> <translation>Τέλος συναλλαγής:</translation> </message> @@ -1643,14 +1652,34 @@ Address: %4 <translation>Επιλογή...</translation> </message> <message> - <source>Minimize</source> - <translation>Ελαχιστοποίηση</translation> + <source>per kilobyte</source> + <translation>ανά kilobyte</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Προτεινόμενο: </translation> + </message> + <message> + <source>Custom:</source> + <translation>Προσαρμογή:</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Χρόνος επικύρωσης:</translation> + </message> + <message> + <source>normal</source> + <translation>κανονικό</translation> </message> <message> <source>fast</source> <translation>Γρήγορο</translation> </message> <message> + <source>(confirmation may take longer)</source> + <translation>(η επικύρωση ίσως χρειαστεί περισσότερο χρόνο)</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Αποστολή σε πολλούς αποδέκτες ταυτόχρονα</translation> </message> @@ -1727,10 +1756,6 @@ Address: %4 <translation>ή</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Η διεύθυνση του αποδέκτη δεν είναι σωστή. Παρακαλώ ελέγξτε ξανά.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Το ποσό πληρωμής πρέπει να είναι μεγαλύτερο από 0.</translation> </message> @@ -1743,10 +1768,6 @@ Address: %4 <translation>Το σύνολο υπερβαίνει το υπόλοιπό σας όταν συμπεριληφθεί και η αμοιβή %1</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Βρέθηκε η ίδια διεύθυνση δύο φορές. Επιτρέπεται μία μόνο εγγραφή για κάθε διεύθυνση, σε κάθε διαδικασία αποστολής.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Η δημιουργία της συναλλαγής απέτυχε!</translation> </message> @@ -1794,12 +1815,20 @@ Address: %4 <translation>Επιλογή διεύθυνσης που έχει ήδη χρησιμοποιηθεί</translation> </message> <message> + <source>This is a normal payment.</source> + <translation>Αυτή είναι μια απλή πληρωμή.</translation> + </message> + <message> + <source>The Bitcoin address to send the payment to</source> + <translation>Η διεύθυνση Bitcoin που θα σταλεί η πληρωμή</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> <message> <source>Paste address from clipboard</source> - <translation>Επικόλληση διεύθυνσης από το πρόχειρο</translation> + <translation>Επικόλληση διεύθυνσης από το βιβλίο διευθύνσεων</translation> </message> <message> <source>Alt+P</source> @@ -1814,6 +1843,10 @@ Address: %4 <translation>Μήνυμα:</translation> </message> <message> + <source>Enter a label for this address to add it to the list of used addresses</source> + <translation>Εισάγεται μία ετικέτα για αυτή την διεύθυνση για να προστεθεί στη λίστα με τις χρησιμοποιημένες διευθύνσεις</translation> + </message> + <message> <source>Pay To:</source> <translation>Πληρωμή σε:</translation> </message> @@ -1844,10 +1877,6 @@ Address: %4 <translation>&Υπογραφή Μηνύματος</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Μπορείτε να υπογράφετε μηνύματα με τις διευθύνσεις σας, ώστε ν' αποδεικνύετε πως αυτές σας ανήκουν. Αποφεύγετε να υπογράφετε κάτι αόριστο καθώς ενδέχεται να εξαπατηθείτε. Υπογράφετε μόνο πλήρης δηλώσεις με τις οποίες συμφωνείτε.</translation> - </message> - <message> <source>The Bitcoin address to sign the message with</source> <translation>Διεύθυνση Bitcoin που θα σταλεί το μήνυμα</translation> </message> @@ -1900,10 +1929,6 @@ Address: %4 <translation>&Επιβεβαίωση μηνύματος</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Πληκτρολογήστε την υπογραφή διεύθυνσης, μήνυμα (βεβαιωθείτε ότι έχετε αντιγράψει τις αλλαγές γραμμής, κενά, tabs, κ.λπ. ακριβώς) και την υπογραφή παρακάτω, για να ελέγξει το μήνυμα. Να είστε προσεκτικοί για να μην διαβάσετε περισσότερα στην υπογραφή ό, τι είναι στην υπογραφή ίδιο το μήνυμα , για να μην εξαπατηθούν από έναν άνθρωπο -in - the-middle επίθεση.</translation> - </message> - <message> <source>The Bitcoin address the message was signed with</source> <translation>Διεύθυνση Bitcoin η οποία το μήνυμα έχει υπογραφεί</translation> </message> @@ -2020,10 +2045,6 @@ Address: %4 <source>Status</source> <translation>Κατάσταση</translation> </message> - <message numerus="yes"> - <source>, broadcast through %n node(s)</source> - <translation><numerusform>, έχει μεταδοθεί μέσω %n κόμβων</numerusform><numerusform>, έχει μεταδοθεί μέσω %n κόμβων</numerusform></translation> - </message> <message> <source>Date</source> <translation>Ημερομηνία</translation> @@ -2060,10 +2081,6 @@ Address: %4 <source>Credit</source> <translation>Πίστωση </translation> </message> - <message numerus="yes"> - <source>matures in %n more block(s)</source> - <translation><numerusform>ωρίμανση σε %n επιπλέον μπλοκ</numerusform><numerusform>ωρίμανση σε %n επιπλέον μπλοκ</numerusform></translation> - </message> <message> <source>not accepted</source> <translation>μη αποδεκτό</translation> @@ -2136,10 +2153,6 @@ Address: %4 <source>, has not been successfully broadcast yet</source> <translation>, δεν έχει ακόμα μεταδοθεί μ' επιτυχία</translation> </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>Ανοιχτό για %n μπλοκ</numerusform><numerusform>Ανοιχτό για %n μπλοκ</numerusform></translation> - </message> <message> <source>unknown</source> <translation>άγνωστο</translation> @@ -2167,14 +2180,6 @@ Address: %4 <translation>Τύπος</translation> </message> <message> - <source>Address</source> - <translation>Διεύθυνση</translation> - </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>Ανοιχτό για %n μπλοκ</numerusform><numerusform>Ανοιχτό για %n μπλοκ</numerusform></translation> - </message> - <message> <source>Open until %1</source> <translation>Ανοιχτό μέχρι %1</translation> </message> @@ -2195,6 +2200,10 @@ Address: %4 <translation>Offline</translation> </message> <message> + <source>Label</source> + <translation>Επιγραφή</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Ανεπιβεβαίωτες</translation> </message> @@ -2204,7 +2213,7 @@ Address: %4 </message> <message> <source>Received with</source> - <translation>Παραλαβή με</translation> + <translation>Ελήφθη με</translation> </message> <message> <source>Received from</source> @@ -2212,7 +2221,7 @@ Address: %4 </message> <message> <source>Sent to</source> - <translation>Αποστολή προς</translation> + <translation>Απεστάλη προς</translation> </message> <message> <source>Payment to yourself</source> @@ -2243,10 +2252,6 @@ Address: %4 <translation>Είδος συναλλαγής.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Διεύθυνση αποστολής της συναλλαγής.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Ποσό που αφαιρέθηκε ή προστέθηκε στο υπόλοιπο.</translation> </message> @@ -2354,6 +2359,10 @@ Address: %4 <translation>Επιτυχής εξαγωγή</translation> </message> <message> + <source>The transaction history was successfully saved to %1.</source> + <translation>Το ιστορικό συναλλαγών αποθηκεύτηκε επιτυχώς στο %1.</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Αρχείο οριοθετημένο με κόμματα (*.csv)</translation> </message> @@ -2392,7 +2401,11 @@ Address: %4 </context> <context> <name>UnitDisplayStatusBarControl</name> - </context> + <message> + <source>Unit to show amounts in. Click to select another unit.</source> + <translation>Μονάδα μέτρησης προβολής ποσών. Κάντε κλικ για επιλογή άλλης μονάδας.</translation> + </message> +</context> <context> <name>WalletFrame</name> <message> @@ -2430,6 +2443,10 @@ Address: %4 <translation>Αποτυχία κατά τη δημιουργία αντιγράφου</translation> </message> <message> + <source>There was an error trying to save the wallet data to %1.</source> + <translation>Παρουσιάστηκε σφάλμα κατά την αποθήκευση των δεδομένων πορτοφολιού στο %1.</translation> + </message> + <message> <source>The wallet data was successfully saved to %1.</source> <translation>Τα δεδομένα πορτοφολιού αποθηκεύτηκαν με επιτυχία στο %1.</translation> </message> @@ -2521,10 +2538,6 @@ Address: %4 <translation>Εντοπισθηκε διεφθαρμενη βαση δεδομενων των μπλοκ</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Ανακαλύψτε την δικη σας IP διεύθυνση (προεπιλογή: 1 όταν ακούει και δεν - externalip) </translation> - </message> - <message> <source>Do you want to rebuild the block database now?</source> <translation>Θελετε να δημιουργηθει τωρα η βαση δεδομενων του μπλοκ? </translation> </message> @@ -2569,8 +2582,8 @@ Address: %4 <translation>Δεν ειναι αρκετες περιγραφες αρχείων διαθέσιμες.</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Εισαγωγή μπλοκ από εξωτερικό αρχείο blk000?.dat</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>Μόνο σύνδεση σε κόμβους του δικτύου <net> (ipv4, ipv6 ή onion)</translation> </message> <message> <source>Specify wallet file (within data directory)</source> @@ -2585,6 +2598,10 @@ Address: %4 <translation>Επαλήθευση πορτοφολιου... </translation> </message> <message> + <source>Wallet %s resides outside data directory %s</source> + <translation>Το πορτοφόλι %s βρίσκεται έξω από το φάκελο δεδομένων %s</translation> + </message> + <message> <source>Wallet options:</source> <translation>Επιλογές πορτοφολιού:</translation> </message> @@ -2597,6 +2614,14 @@ Address: %4 <translation>Αδυναμία κλειδώματος του φακέλου δεδομένων %s. Πιθανώς το Bitcoin να είναι ήδη ενεργό.</translation> </message> <message> + <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Προειδοποίηση: Παρακαλώ ελέγξτε ότι η ημερομηνία και ώρα του υπολογιστή σας είναι σωστά ρυθμισμένες! Εάν το ρολόι σας είναι λάθος το Bitcoin Core δεν θα λειτουργήσει σωστά. </translation> + </message> + <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Επιλογή φακέλου δεδομένων στην εκκίνηση (προεπιλεγμένο: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Σύνδεση μέσω διαμεσολαβητή SOCKS5</translation> </message> @@ -2609,6 +2634,10 @@ Address: %4 <translation>Σφάλμα φόρτωσης wallet.dat: Το Πορτοφόλι απαιτεί μια νεότερη έκδοση του Bitcoin</translation> </message> <message> + <source>Error reading from database, shutting down.</source> + <translation>Σφάλμα ανάγνωσης από τη βάση δεδομένων, γίνεται τερματισμός.</translation> + </message> + <message> <source>Error: Unsupported argument -tor found, use -onion.</source> <translation>Σφάλμα: Μη συμβατή παράμετρος -tor. Χρησιμοποιήσε την παράμετρο -onion</translation> </message> @@ -2617,6 +2646,10 @@ Address: %4 <translation>Πληροφορία</translation> </message> <message> + <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source> + <translation>Η εκκίνηση ελέγχου ορθότητας απέτυχε. Γίνεται τερματισμός του Bitcoin Core.</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Μη έγκυρο ποσό για την παράμετρο -paytxfee=<amount>: '%s'</translation> </message> @@ -2625,14 +2658,38 @@ Address: %4 <translation>Μη έγκυρο ποσό για την παράμετρο -paytxfee=<amount>: '%s'</translation> </message> <message> + <source>Node relay options:</source> + <translation>Επιλογές αναμετάδοσης κόμβου: </translation> + </message> + <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Ρυθμίσεις SSL: (ανατρέξτε στο Bitcoin Wiki για οδηγίες ρυθμίσεων SSL)</translation> </message> <message> + <source>RPC server options:</source> + <translation>Επιλογές διακομιστή RPC:</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Αποστολή πληροφοριών εντοπισμού σφαλμάτων στην κονσόλα αντί του αρχείου debug.log</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Ορίστε SSL root certificates για αίτηση πληρωμής (default: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Όρισε γλώσσα, για παράδειγμα "de_DE"(προεπιλογή:τοπικές ρυθμίσεις)</translation> + </message> + <message> + <source>Show all debugging options (usage: --help -help-debug)</source> + <translation>Προβολή όλων των επιλογών εντοπισμού σφαλμάτων (χρήση: --help -help-debug)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Εμφάνισε την οθόνη εκκίνησης κατά την εκκίνηση(προεπιλογή:1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Συρρίκνωση του αρχείο debug.log κατα την εκκίνηση του πελάτη (προεπιλογή: 1 όταν δεν-debug)</translation> </message> @@ -2641,6 +2698,10 @@ Address: %4 <translation>Η υπογραφή συναλλαγής απέτυχε </translation> </message> <message> + <source>Start minimized</source> + <translation>Έναρξη ελαχιστοποιημένο</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Η εφαρμογή είναι σε πειραματικό στάδιο.</translation> </message> @@ -2669,10 +2730,6 @@ Address: %4 <translation>Προειδοποίηση</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Προειδοποίηση: Αυτή η έκδοση είναι ξεπερασμένη, απαιτείται αναβάθμιση </translation> - </message> - <message> <source>Zapping all transactions from wallet...</source> <translation>Μεταφορά όλων των συναλλαγών απο το πορτοφόλι</translation> </message> @@ -2737,10 +2794,6 @@ Address: %4 <translation>Σφάλμα φόρτωσης αρχείου wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Επιβολή ασφαλής λειτουργίας (προεπιλογή: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Δημιουργία νομισμάτων (προκαθορισμος: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 2555cdbb62..3ebb4d0bf6 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -104,7 +104,7 @@ <translation>&Edit</translation> </message> <message> - <location line="+194"/> + <location line="+193"/> <source>Export Address List</source> <translation type="unfinished"></translation> </message> @@ -195,12 +195,7 @@ <translation>Change passphrase</translation> </message> <message> - <location line="+1"/> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Enter the old and new passphrase to the wallet.</translation> - </message> - <message> - <location line="+45"/> + <location line="+46"/> <source>Confirm wallet encryption</source> <translation>Confirm wallet encryption</translation> </message> @@ -242,7 +237,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+93"/> + <location line="+23"/> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+70"/> <location line="+7"/> <location line="+42"/> <location line="+6"/> @@ -284,29 +284,42 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <location filename="../bantablemodel.cpp" line="+88"/> + <source>IP/Netmask</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+0"/> + <source>Banned Until</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> - <location filename="../bitcoingui.cpp" line="+326"/> + <location filename="../bitcoingui.cpp" line="+324"/> <source>Sign &message...</source> <translation>Sign &message...</translation> </message> <message> - <location line="+342"/> + <location line="+353"/> <source>Synchronizing with network...</source> <translation>Synchronizing with network...</translation> </message> <message> - <location line="-418"/> + <location line="-429"/> <source>&Overview</source> <translation>&Overview</translation> </message> <message> - <location line="-134"/> + <location line="-130"/> <source>Node</source> <translation type="unfinished"></translation> </message> <message> - <location line="+135"/> + <location line="+131"/> <source>Show general overview of wallet</source> <translation>Show general overview of wallet</translation> </message> @@ -376,12 +389,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+175"/> + <location line="+180"/> <source>Bitcoin Core client</source> <translation type="unfinished"></translation> </message> <message> - <location line="+157"/> + <location line="+163"/> <source>Importing blocks from disk...</source> <translation>Importing blocks from disk...</translation> </message> @@ -391,7 +404,7 @@ <translation>Reindexing blocks on disk...</translation> </message> <message> - <location line="-416"/> + <location line="-427"/> <source>Send coins to a Bitcoin address</source> <translation>Send coins to a Bitcoin address</translation> </message> @@ -421,17 +434,17 @@ <translation>&Verify message...</translation> </message> <message> - <location line="+439"/> + <location line="+450"/> <source>Bitcoin</source> <translation>Bitcoin</translation> </message> <message> - <location line="-653"/> + <location line="-660"/> <source>Wallet</source> <translation>Wallet</translation> </message> <message> - <location line="+143"/> + <location line="+139"/> <source>&Send</source> <translation>&Send</translation> </message> @@ -471,7 +484,7 @@ <translation>Verify messages to ensure they were signed with specified Bitcoin addresses</translation> </message> <message> - <location line="+49"/> + <location line="+53"/> <source>&File</source> <translation>&File</translation> </message> @@ -496,7 +509,7 @@ <translation type="unfinished">Bitcoin Core</translation> </message> <message> - <location line="+164"/> + <location line="+160"/> <source>Request payments (generates QR codes and bitcoin: URIs)</source> <translation type="unfinished"></translation> </message> @@ -536,7 +549,7 @@ <translation type="unfinished"></translation> </message> <message numerus="yes"> - <location line="+309"/> + <location line="+320"/> <source>%n active connection(s) to Bitcoin network</source> <translation> <numerusform>%n active connection to Bitcoin network</numerusform> @@ -549,7 +562,15 @@ <translation>No block source available...</translation> </message> <message numerus="yes"> - <location line="+35"/> + <location line="+9"/> + <source>Processed %n block(s) of transaction history.</source> + <translation> + <numerusform>Processed %n block of transaction history.</numerusform> + <numerusform>Processed %n blocks of transaction history.</numerusform> + </translation> + </message> + <message numerus="yes"> + <location line="+26"/> <source>%n hour(s)</source> <translation> <numerusform>%n hour</numerusform> @@ -621,16 +642,8 @@ <source>Up to date</source> <translation>Up to date</translation> </message> - <message numerus="yes"> - <location line="-5"/> - <source>Processed %n blocks of transaction history.</source> - <translation type="unfinished"> - <numerusform></numerusform> - <numerusform></numerusform> - </translation> - </message> <message> - <location line="+49"/> + <location line="+44"/> <source>Catching up...</source> <translation>Catching up...</translation> </message> @@ -688,7 +701,7 @@ <context> <name>ClientModel</name> <message> - <location filename="../clientmodel.cpp" line="+141"/> + <location filename="../clientmodel.cpp" line="+143"/> <source>Network Alert</source> <translation>Network Alert</translation> </message> @@ -791,7 +804,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../coincontroldialog.cpp" line="+46"/> + <location filename="../coincontroldialog.cpp" line="+47"/> <source>Copy address</source> <translation type="unfinished">Copy address</translation> </message> @@ -912,7 +925,22 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+177"/> + <location line="+160"/> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+8"/> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation type="unfinished"></translation> </message> @@ -927,12 +955,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+16"/> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> + <location line="+17"/> <location line="+5"/> <source>This means a fee of at least %1 per kB is required.</source> <translation type="unfinished"></translation> @@ -948,18 +971,8 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+55"/> - <location line="+61"/> + <location line="+58"/> + <location line="+60"/> <source>(no label)</source> <translation type="unfinished">(no label)</translation> </message> @@ -1045,7 +1058,7 @@ <context> <name>FreespaceChecker</name> <message> - <location filename="../intro.cpp" line="+69"/> + <location filename="../intro.cpp" line="+68"/> <source>A new data directory will be created.</source> <translation>A new data directory will be created.</translation> </message> @@ -1240,6 +1253,7 @@ </message> <message> <location line="+44"/> + <location line="+187"/> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation type="unfinished"></translation> </message> @@ -1280,7 +1294,7 @@ <translation>&Reset Options</translation> </message> <message> - <location line="-317"/> + <location line="-504"/> <source>&Network</source> <translation>&Network</translation> </message> @@ -1346,21 +1360,61 @@ </message> <message> <location line="+9"/> + <location line="+187"/> <source>Proxy &IP:</source> <translation>Proxy &IP:</translation> </message> <message> - <location line="+32"/> + <location line="-155"/> + <location line="+187"/> <source>&Port:</source> <translation>&Port:</translation> </message> <message> - <location line="+25"/> + <location line="-162"/> + <location line="+187"/> <source>Port of the proxy (e.g. 9050)</source> <translation>Port of the proxy (e.g. 9050)</translation> </message> <message> - <location line="+36"/> + <location line="-163"/> + <source>Used for reaching peers via:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+13"/> + <location line="+23"/> + <location line="+23"/> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="-36"/> + <source>IPv4</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+23"/> + <source>IPv6</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+23"/> + <source>Tor</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+25"/> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+102"/> <source>&Window</source> <translation>&Window</translation> </message> @@ -1400,12 +1454,12 @@ <translation>Choose the default subdivision unit to show in the interface and when sending coins.</translation> </message> <message> - <location line="-253"/> + <location line="-440"/> <source>Whether to show coin control features or not.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+415"/> + <location line="+602"/> <source>&OK</source> <translation>&OK</translation> </message> @@ -1415,7 +1469,7 @@ <translation>&Cancel</translation> </message> <message> - <location filename="../optionsdialog.cpp" line="+75"/> + <location filename="../optionsdialog.cpp" line="+83"/> <source>default</source> <translation>default</translation> </message> @@ -1425,28 +1479,28 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+76"/> + <location line="+83"/> <source>Confirm options reset</source> <translation>Confirm options reset</translation> </message> <message> <location line="+1"/> - <location line="+29"/> + <location line="+30"/> <source>Client restart required to activate changes.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-29"/> - <source>Client will be shutdown, do you want to proceed?</source> + <location line="-30"/> + <source>Client will be shut down. Do you want to proceed?</source> <translation type="unfinished"></translation> </message> <message> - <location line="+33"/> + <location line="+34"/> <source>This change would require a client restart.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+25"/> + <location line="+24"/> <source>The supplied proxy address is invalid.</source> <translation>The supplied proxy address is invalid.</translation> </message> @@ -1459,13 +1513,13 @@ <translation>Form</translation> </message> <message> - <location line="+53"/> - <location line="+372"/> + <location line="+59"/> + <location line="+386"/> <source>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source> <translation>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.</translation> </message> <message> - <location line="-133"/> + <location line="-139"/> <source>Watch-only:</source> <translation type="unfinished"></translation> </message> @@ -1500,12 +1554,12 @@ <translation>Mined balance that has not yet matured</translation> </message> <message> - <location line="-163"/> + <location line="-177"/> <source>Balances</source> <translation type="unfinished"></translation> </message> <message> - <location line="+147"/> + <location line="+161"/> <source>Total:</source> <translation>Total:</translation> </message> @@ -1544,17 +1598,11 @@ <source>Current total balance in watch-only addresses</source> <translation type="unfinished"></translation> </message> - <message> - <location filename="../overviewpage.cpp" line="+133"/> - <location line="+1"/> - <source>out of sync</source> - <translation>out of sync</translation> - </message> </context> <context> <name>PaymentServer</name> <message> - <location filename="../paymentserver.cpp" line="+434"/> + <location filename="../paymentserver.cpp" line="+432"/> <location line="+14"/> <location line="+7"/> <source>URI handling</source> @@ -1566,16 +1614,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+88"/> + <location line="+83"/> <location line="+9"/> <location line="+31"/> <location line="+10"/> <location line="+17"/> + <location line="+88"/> <source>Payment request rejected</source> <translation type="unfinished"></translation> </message> <message> - <location line="-67"/> + <location line="-155"/> <source>Payment request network doesn't match client network.</source> <translation type="unfinished"></translation> </message> @@ -1590,17 +1639,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-263"/> - <location line="+221"/> + <location line="-258"/> + <location line="+216"/> <location line="+42"/> - <location line="+114"/> + <location line="+113"/> <location line="+14"/> <location line="+18"/> <source>Payment request error</source> <translation type="unfinished"></translation> </message> <message> - <location line="-408"/> + <location line="-402"/> <source>Cannot start bitcoin: click-to-pay handler</source> <translation type="unfinished"></translation> </message> @@ -1625,7 +1674,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+75"/> + <location line="+70"/> <source>Payment request expired.</source> <translation type="unfinished"></translation> </message> @@ -1646,17 +1695,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+44"/> <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> - <source>Payment request DoS protection</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+5"/> + <location line="+9"/> <source>Error communicating with %1: %2</source> <translation type="unfinished"></translation> </message> @@ -1684,7 +1728,7 @@ <context> <name>PeerTableModel</name> <message> - <location filename="../peertablemodel.cpp" line="+118"/> + <location filename="../peertablemodel.cpp" line="+117"/> <source>User Agent</source> <translation type="unfinished"></translation> </message> @@ -1712,7 +1756,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+748"/> + <location line="+761"/> <source>%1 d</source> <translation type="unfinished"></translation> </message> @@ -1774,7 +1818,7 @@ <context> <name>RPCConsole</name> <message> - <location filename="../forms/rpcconsole.ui" line="+46"/> + <location filename="../forms/debugwindow.ui" line="+46"/> <source>Client name</source> <translation>Client name</translation> </message> @@ -1783,13 +1827,16 @@ <location line="+23"/> <location line="+26"/> <location line="+26"/> + <location line="+26"/> <location line="+23"/> <location line="+23"/> <location line="+36"/> <location line="+23"/> <location line="+36"/> <location line="+23"/> - <location line="+465"/> + <location line="+533"/> + <location line="+23"/> + <location line="+23"/> <location line="+23"/> <location line="+23"/> <location line="+23"/> @@ -1802,12 +1849,13 @@ <location line="+23"/> <location line="+23"/> <location line="+23"/> + <location line="+26"/> <location line="+23"/> <source>N/A</source> <translation>N/A</translation> </message> <message> - <location line="-990"/> + <location line="-1156"/> <source>Client version</source> <translation>Client version</translation> </message> @@ -1827,7 +1875,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+53"/> + <location line="+79"/> <source>Using OpenSSL version</source> <translation>Using OpenSSL version</translation> </message> @@ -1887,14 +1935,24 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+39"/> - <location filename="../rpcconsole.cpp" line="+238"/> - <location line="+326"/> + <location line="+50"/> + <source>Banned peers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+57"/> + <location filename="../rpcconsole.cpp" line="+281"/> + <location line="+560"/> <source>Select a peer to view detailed information.</source> <translation type="unfinished"></translation> </message> <message> <location line="+25"/> + <source>Whitelisted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+23"/> <source>Direction</source> <translation type="unfinished"></translation> </message> @@ -1904,27 +1962,33 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+23"/> - <source>User Agent</source> + <location line="+69"/> + <source>Starting Block</source> <translation type="unfinished"></translation> </message> <message> <location line="+23"/> - <source>Services</source> + <source>Synced Headers</source> <translation type="unfinished"></translation> </message> <message> <location line="+23"/> - <source>Starting Height</source> + <source>Synced Blocks</source> <translation type="unfinished"></translation> </message> <message> - <location line="+23"/> - <source>Sync Height</source> + <location line="-913"/> + <location line="+821"/> + <source>User Agent</source> <translation type="unfinished"></translation> </message> <message> <location line="+23"/> + <source>Services</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+92"/> <source>Ban Score</source> <translation type="unfinished"></translation> </message> @@ -1960,11 +2024,21 @@ </message> <message> <location line="+23"/> + <source>The duration of a currently outstanding ping.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Ping Wait</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+23"/> <source>Time Offset</source> <translation type="unfinished"></translation> </message> <message> - <location line="-764"/> + <location line="-904"/> <source>Last block time</source> <translation>Last block time</translation> </message> @@ -1994,7 +2068,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../rpcconsole.cpp" line="-164"/> + <location filename="../rpcconsole.cpp" line="-333"/> <source>In:</source> <translation type="unfinished"></translation> </message> @@ -2004,7 +2078,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../forms/rpcconsole.ui" line="-357"/> + <location filename="../forms/debugwindow.ui" line="-357"/> <source>Build date</source> <translation>Build date</translation> </message> @@ -2019,7 +2093,45 @@ <translation>Clear console</translation> </message> <message> - <location filename="../rpcconsole.cpp" line="-36"/> + <location filename="../rpcconsole.cpp" line="-150"/> + <source>&Disconnect Node</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <location line="+1"/> + <location line="+1"/> + <location line="+1"/> + <source>Ban Node for</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="-3"/> + <source>1 &hour</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>1 &day</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>1 &week</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>1 &year</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+46"/> + <source>&Unban Node</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+64"/> <source>Welcome to the Bitcoin Core RPC console.</source> <translation type="unfinished"></translation> </message> @@ -2054,7 +2166,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+95"/> + <location line="+88"/> + <source>(node id: %1)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> <source>via %1</source> <translation type="unfinished"></translation> </message> @@ -2065,7 +2182,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+9"/> <source>Inbound</source> <translation type="unfinished"></translation> </message> @@ -2075,14 +2192,19 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>Unknown</source> + <location line="+2"/> + <source>Yes</source> <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> - <location line="+1"/> - <source>Fetching...</source> + <location line="+0"/> + <source>No</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+12"/> + <location line="+6"/> + <source>Unknown</source> <translation type="unfinished"></translation> </message> </context> @@ -2177,7 +2299,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../receivecoinsdialog.cpp" line="+45"/> + <location filename="../receivecoinsdialog.cpp" line="+46"/> <source>Copy label</source> <translation type="unfinished">Copy label</translation> </message> @@ -2302,7 +2424,7 @@ <name>SendCoinsDialog</name> <message> <location filename="../forms/sendcoinsdialog.ui" line="+14"/> - <location filename="../sendcoinsdialog.cpp" line="+543"/> + <location filename="../sendcoinsdialog.cpp" line="+545"/> <source>Send Coins</source> <translation>Send Coins</translation> </message> @@ -2547,22 +2669,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+244"/> - <source>Total Amount %1 (= %2)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+2"/> + <location line="+246"/> <source>or</source> <translation type="unfinished"></translation> </message> <message> - <location line="+193"/> - <source>The recipient address is not valid, please recheck.</source> - <translation>The recipient address is not valid, please recheck.</translation> - </message> - <message> - <location line="+3"/> + <location line="+196"/> <source>The amount to pay must be larger than 0.</source> <translation>The amount to pay must be larger than 0.</translation> </message> @@ -2577,12 +2689,7 @@ <translation>The total exceeds your balance when the %1 transaction fee is included.</translation> </message> <message> - <location line="+3"/> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Duplicate address found, can only send to each address once per send operation.</translation> - </message> - <message> - <location line="+3"/> + <location line="+6"/> <source>Transaction creation failed!</source> <translation type="unfinished"></translation> </message> @@ -2605,8 +2712,8 @@ <location line="+110"/> <source>Estimated to begin confirmation within %n block(s).</source> <translation type="unfinished"> - <numerusform></numerusform> - <numerusform></numerusform> + <numerusform>Estimated to begin confirmation within %n block.</numerusform> + <numerusform>Estimated to begin confirmation within %n blocks.</numerusform> </translation> </message> <message> @@ -2615,12 +2722,27 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+129"/> + <location line="-309"/> + <source>Total Amount %1<span style='font-size:10pt;font-weight:normal;'><br />(=%2)</span></source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+195"/> + <source>The recipient address is not valid. Please recheck.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+12"/> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+231"/> <source>Warning: Invalid Bitcoin address</source> <translation type="unfinished"></translation> </message> <message> - <location line="+20"/> + <location line="+19"/> <source>(no label)</source> <translation type="unfinished">(no label)</translation> </message> @@ -2630,7 +2752,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-692"/> + <location line="-691"/> <source>Copy dust</source> <translation type="unfinished"></translation> </message> @@ -2648,14 +2770,14 @@ <context> <name>SendCoinsEntry</name> <message> - <location filename="../forms/sendcoinsentry.ui" line="+149"/> - <location line="+535"/> - <location line="+536"/> + <location filename="../forms/sendcoinsentry.ui" line="+155"/> + <location line="+539"/> + <location line="+533"/> <source>A&mount:</source> <translation>A&mount:</translation> </message> <message> - <location line="-1184"/> + <location line="-1185"/> <source>Pay &To:</source> <translation>Pay &To:</translation> </message> @@ -2675,12 +2797,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-40"/> + <location line="-46"/> <source>This is a normal payment.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+33"/> + <location line="+39"/> <source>The Bitcoin address to send the payment to</source> <translation type="unfinished"></translation> </message> @@ -2701,13 +2823,13 @@ </message> <message> <location line="+7"/> - <location line="+544"/> - <location line="+536"/> + <location line="+548"/> + <location line="+533"/> <source>Remove this entry</source> <translation type="unfinished"></translation> </message> <message> - <location line="-1020"/> + <location line="-1021"/> <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> <translation type="unfinished"></translation> </message> @@ -2722,17 +2844,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+436"/> + <location line="+443"/> <source>This is an unauthenticated payment request.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+532"/> + <location line="+529"/> <source>This is an authenticated payment request.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-1005"/> + <location line="-1009"/> <source>Enter a label for this address to add it to the list of used addresses</source> <translation type="unfinished"></translation> </message> @@ -2742,14 +2864,14 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+444"/> - <location line="+532"/> + <location line="+448"/> + <location line="+529"/> <source>Pay To:</source> <translation type="unfinished"></translation> </message> <message> - <location line="-498"/> - <location line="+536"/> + <location line="-495"/> + <location line="+533"/> <source>Memo:</source> <translation type="unfinished"></translation> </message> @@ -2878,7 +3000,7 @@ <translation>Reset all verify message fields</translation> </message> <message> - <location filename="../signverifymessagedialog.cpp" line="+40"/> + <location filename="../signverifymessagedialog.cpp" line="+41"/> <source>Click "Sign Message" to generate signature</source> <translation>Click "Sign Message" to generate signature</translation> </message> @@ -2962,7 +3084,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../networkstyle.cpp" line="+20"/> + <location filename="../networkstyle.cpp" line="+19"/> <source>[testnet]</source> <translation>[testnet]</translation> </message> @@ -2978,7 +3100,7 @@ <context> <name>TransactionDesc</name> <message> - <location filename="../transactiondesc.cpp" line="+35"/> + <location filename="../transactiondesc.cpp" line="+32"/> <source>Open until %1</source> <translation>Open until %1</translation> </message> @@ -3202,7 +3324,7 @@ <context> <name>TransactionTableModel</name> <message> - <location filename="../transactiontablemodel.cpp" line="+230"/> + <location filename="../transactiontablemodel.cpp" line="+233"/> <source>Date</source> <translation>Date</translation> </message> @@ -3338,7 +3460,7 @@ <context> <name>TransactionView</name> <message> - <location filename="../transactionview.cpp" line="+68"/> + <location filename="../transactionview.cpp" line="+69"/> <location line="+16"/> <source>All</source> <translation>All</translation> @@ -3525,7 +3647,7 @@ <context> <name>WalletFrame</name> <message> - <location filename="../walletframe.cpp" line="+26"/> + <location filename="../walletframe.cpp" line="+27"/> <source>No wallet has been loaded.</source> <translation type="unfinished"></translation> </message> @@ -3541,7 +3663,7 @@ <context> <name>WalletView</name> <message> - <location filename="../walletview.cpp" line="+45"/> + <location filename="../walletview.cpp" line="+46"/> <source>&Export</source> <translation>&Export</translation> </message> @@ -3551,7 +3673,7 @@ <translation>Export the data in the current tab to a file</translation> </message> <message> - <location line="+189"/> + <location line="+194"/> <source>Backup Wallet</source> <translation>Backup Wallet</translation> </message> @@ -3584,57 +3706,112 @@ <context> <name>bitcoin-core</name> <message> - <location filename="../bitcoinstrings.cpp" line="+269"/> + <location filename="../bitcoinstrings.cpp" line="+249"/> <source>Options:</source> <translation>Options:</translation> </message> <message> - <location line="+35"/> + <location line="+30"/> <source>Specify data directory</source> <translation>Specify data directory</translation> </message> <message> - <location line="-94"/> + <location line="-87"/> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Connect to a node to retrieve peer addresses, and disconnect</translation> </message> <message> - <location line="+97"/> + <location line="+90"/> <source>Specify your own public address</source> <translation>Specify your own public address</translation> </message> <message> - <location line="-116"/> + <location line="-107"/> <source>Accept command line and JSON-RPC commands</source> <translation>Accept command line and JSON-RPC commands</translation> </message> <message> - <location line="+94"/> + <location line="-117"/> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying (default: %s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+15"/> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+9"/> + <source>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)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+109"/> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+37"/> + <source>Pruning blockstore...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+9"/> <source>Run in the background as a daemon and accept commands</source> <translation>Run in the background as a daemon and accept commands</translation> </message> <message> - <location line="+42"/> + <location line="+32"/> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> <source>Use the test network</source> <translation>Use the test network</translation> </message> <message> - <location line="-135"/> + <location line="-123"/> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Accept connections from outside (default: 1 if no -proxy or -connect)</translation> </message> <message> - <location line="-170"/> + <location line="-157"/> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Bind to given address and always listen on it. Use [host]:port notation for IPv6</translation> </message> <message> - <location line="+13"/> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+6"/> + <location line="+16"/> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation type="unfinished"></translation> </message> @@ -3644,42 +3821,52 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation type="unfinished"></translation> - </message> - <message> <location line="+11"/> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</translation> </message> <message> - <location line="+20"/> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> + <location line="+57"/> + <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+36"/> - <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> + <location line="+6"/> + <source>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+7"/> <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source> <translation>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</translation> </message> <message> - <location line="+20"/> + <location line="+7"/> <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+3"/> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+6"/> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</translation> </message> <message> - <location line="+9"/> + <location line="+3"/> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</translation> </message> @@ -3704,7 +3891,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+11"/> <source>(default: 1)</source> <translation type="unfinished"></translation> </message> @@ -3714,7 +3901,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+10"/> + <location line="+8"/> <source>Attempt to recover private keys from a corrupt wallet.dat</source> <translation>Attempt to recover private keys from a corrupt wallet.dat</translation> </message> @@ -3724,7 +3911,7 @@ <translation>Block creation options:</translation> </message> <message> - <location line="+8"/> + <location line="+7"/> <source>Connect only to the specified node(s)</source> <translation>Connect only to the specified node(s)</translation> </message> @@ -3739,12 +3926,12 @@ <translation>Corrupted block database detected</translation> </message> <message> - <location line="+2"/> + <location line="+1"/> <source>Debugging/Testing options:</source> <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> + <location line="+1"/> <source>Do not load the wallet and disable wallet RPC calls</source> <translation type="unfinished"></translation> </message> @@ -3755,6 +3942,26 @@ </message> <message> <location line="+2"/> + <source>Enable publish hash block in <address></source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Enable publish hash transaction in <address></source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Enable publish raw block in <address></source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Enable publish raw transaction in <address></source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> <source>Error initializing block database</source> <translation>Error initializing block database</translation> </message> @@ -3774,12 +3981,7 @@ <translation>Error opening block database</translation> </message> <message> - <location line="+3"/> - <source>Error: A fatal internal error occured, see debug.log for details</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> + <location line="+4"/> <source>Error: Disk space is low!</source> <translation>Error: Disk space is low!</translation> </message> @@ -3789,12 +3991,7 @@ <translation>Failed to listen on any port. Use -listen=0 if you want this.</translation> </message> <message> - <location line="+5"/> - <source>If <category> is not supplied, output all debugging information.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> + <location line="+4"/> <source>Importing...</source> <translation type="unfinished"></translation> </message> @@ -3809,12 +4006,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+20"/> <source>Not enough file descriptors available.</source> <translation>Not enough file descriptors available.</translation> </message> <message> - <location line="+2"/> + <location line="+1"/> <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> <translation type="unfinished"></translation> </message> @@ -3829,12 +4026,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Rebuild block chain index from current blk000??.dat files</translation> - </message> - <message> - <location line="+12"/> + <location line="+14"/> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation type="unfinished"></translation> </message> @@ -3844,22 +4036,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+11"/> <source>Specify wallet file (within data directory)</source> <translation>Specify wallet file (within data directory)</translation> </message> <message> - <location line="+8"/> - <source>This is intended for regression testing tools and app development.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+11"/> + <location line="+17"/> <source>Use UPnP to map the listening port (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> + <location line="+3"/> <source>Verifying blocks...</source> <translation>Verifying blocks...</translation> </message> @@ -3879,27 +4066,27 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> + <location line="+2"/> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>You need to rebuild the database using -reindex to change -txindex</translation> </message> <message> - <location line="-99"/> + <location line="-89"/> <source>Imports blocks from external blk000??.dat file</source> <translation>Imports blocks from external blk000??.dat file</translation> </message> <message> - <location line="-224"/> + <location line="-206"/> <source>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</source> <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+6"/> + <location line="+7"/> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> <translation type="unfinished"></translation> </message> @@ -3914,7 +4101,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> + <location line="+3"/> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation type="unfinished"></translation> </message> @@ -3924,7 +4111,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+6"/> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation type="unfinished"></translation> </message> @@ -3939,42 +4126,22 @@ <translation>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</translation> </message> <message> - <location line="+9"/> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+8"/> + <location line="+17"/> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> + <location line="+3"/> <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+6"/> <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+7"/> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+2"/> + <location line="+18"/> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation type="unfinished"></translation> </message> @@ -3984,17 +4151,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> - <source>Require high priority for relaying free or low-fee transactions (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+2"/> + <location line="+11"/> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation type="unfinished"></translation> </message> @@ -4004,7 +4161,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> + <location line="+8"/> <source>The transaction amount is too small to send after the fee has been deducted</source> <translation type="unfinished"></translation> </message> @@ -4014,37 +4171,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+19"/> + <location line="+18"/> <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> - <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> - <source>Warning: Reverting this setting requires re-downloading the entire blockchain.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+19"/> + <location line="+22"/> <source>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</source> <translation type="unfinished"></translation> </message> @@ -4059,32 +4191,17 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> - <source>(default: 0 = disable pruning blocks,</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> - <source>>%u = target size in MiB to use for block files)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> + <location line="+5"/> <source>Accept public REST requests (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> - <source>Allow self signed root certificates (default: 0)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+4"/> - <source>Can't run with a wallet in prune mode.</source> + <location line="+1"/> + <source>Activating best chain...</source> <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> + <location line="+9"/> <source>Cannot resolve -whitebind address: '%s'</source> <translation type="unfinished"></translation> </message> @@ -4104,12 +4221,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> - <source>Could not parse -rpcbind value %s as network address</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+11"/> + <location line="+15"/> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation type="unfinished"></translation> </message> @@ -4124,11 +4236,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> - <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> - <translation type="unfinished"></translation> - </message> - <message> <location line="+9"/> <source>Information</source> <translation>Information</translation> @@ -4169,7 +4276,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+10"/> <source>Need to specify a port with -whitebind: '%s'</source> <translation type="unfinished"></translation> </message> @@ -4180,31 +4287,26 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <location line="+9"/> - <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> <source>RPC server options:</source> <translation type="unfinished"></translation> </message> <message> <location line="+1"/> - <source>RPC support for HTTP persistent connections (default: %d)</source> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation type="unfinished"></translation> </message> <message> <location line="+1"/> - <source>Randomly drop 1 of every <n> network messages</source> + <source>Receive and display P2P network alerts (default: %u)</source> <translation type="unfinished"></translation> </message> <message> <location line="+1"/> - <source>Randomly fuzz 1 of every <n> network messages</source> + <source>Reducing -maxconnections from %d to %d, because of system limitations.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+6"/> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Send trace/debug info to console instead of debug.log file</translation> </message> @@ -4214,7 +4316,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> + <location line="+1"/> <source>Set SSL root certificates for payment request (default: -system-)</source> <translation type="unfinished"></translation> </message> @@ -4224,7 +4326,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished">Set language, for example "de_DE" (default: system locale)</translation> </message> <message> - <location line="+5"/> + <location line="+4"/> <source>Show all debugging options (usage: --help -help-debug)</source> <translation type="unfinished"></translation> </message> @@ -4249,7 +4351,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished">Start minimized</translation> </message> <message> - <location line="+2"/> + <location line="+1"/> <source>The transaction amount is too small to pay the fee</source> <translation type="unfinished"></translation> </message> @@ -4259,7 +4361,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> + <location line="+2"/> <source>Transaction amount too small</source> <translation>Transaction amount too small</translation> </message> @@ -4289,12 +4391,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>Use UPnP to map the listening port (default: 1 when listening)</translation> - </message> - <message> - <location line="+2"/> + <location line="+6"/> <source>Username for JSON-RPC connections</source> <translation>Username for JSON-RPC connections</translation> </message> @@ -4309,12 +4406,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Warning</translation> </message> <message> - <location line="+1"/> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Warning: This version is obsolete, upgrade required!</translation> - </message> - <message> - <location line="+1"/> + <location line="+2"/> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation type="unfinished"></translation> </message> @@ -4330,6 +4422,11 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <location line="+1"/> + <source>ZeroMQ notification options:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> <source>on startup</source> <translation type="unfinished"></translation> </message> @@ -4339,72 +4436,57 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>wallet.dat corrupt, salvage failed</translation> </message> <message> - <location line="-71"/> + <location line="-64"/> <source>Password for JSON-RPC connections</source> <translation>Password for JSON-RPC connections</translation> </message> <message> - <location line="-206"/> + <location line="-195"/> <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source> <translation>Execute command when the best block changes (%s in cmd is replaced by block hash)</translation> </message> <message> - <location line="+259"/> + <location line="+242"/> <source>Upgrade wallet to latest format</source> <translation>Upgrade wallet to latest format</translation> </message> <message> - <location line="-41"/> + <location line="-36"/> <source>Rescan the block chain for missing wallet transactions</source> <translation>Rescan the block chain for missing wallet transactions</translation> </message> <message> - <location line="+42"/> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Use OpenSSL (https) for JSON-RPC connections</translation> - </message> - <message> - <location line="-12"/> + <location line="+25"/> <source>This help message</source> <translation>This help message</translation> </message> <message> - <location line="-116"/> + <location line="-106"/> <source>Allow DNS lookups for -addnode, -seednode and -connect</source> <translation>Allow DNS lookups for -addnode, -seednode and -connect</translation> </message> <message> - <location line="+61"/> + <location line="+58"/> <source>Loading addresses...</source> <translation>Loading addresses...</translation> </message> <message> - <location line="-33"/> + <location line="-30"/> <source>Error loading wallet.dat: Wallet corrupted</source> <translation>Error loading wallet.dat: Wallet corrupted</translation> </message> <message> - <location line="-212"/> + <location line="-196"/> <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+61"/> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> + <location line="+49"/> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation type="unfinished"></translation> </message> <message> <location line="+11"/> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+2"/> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4419,7 +4501,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+48"/> + <location line="+51"/> <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> <translation type="unfinished"></translation> </message> @@ -4429,32 +4511,17 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> - <source>Acceptable ciphers (default: %s)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+4"/> + <location line="+10"/> <source>Always query for peer addresses via DNS lookup (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+18"/> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+7"/> + <location line="+26"/> <source>Error loading wallet.dat</source> <translation>Error loading wallet.dat</translation> </message> <message> <location line="+11"/> - <source>Force safe mode (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> <source>Generate coins (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4464,7 +4531,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> + <location line="+3"/> <source>Include IP addresses in debug output (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4475,11 +4542,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <location line="+8"/> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation type="unfinished"></translation> </message> @@ -4509,17 +4571,12 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+4"/> + <location line="+7"/> <source>Prepend debug output with timestamp (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+8"/> <source>Relay and mine data carrier transactions (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4529,22 +4586,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+4"/> - <source>Server certificate file (default: %s)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> - <source>Server private key (default: %s)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> + <location line="+8"/> <source>Set key pool size to <n> (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4559,11 +4601,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> <location line="+5"/> <source>Specify configuration file (default: %s)</source> <translation type="unfinished"></translation> @@ -4584,22 +4621,17 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> <location line="+5"/> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> + <location line="+8"/> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Unknown network specified in -onlynet: '%s'</translation> </message> <message> - <location line="-119"/> + <location line="-111"/> <source>Cannot resolve -bind address: '%s'</source> <translation>Cannot resolve -bind address: '%s'</translation> </message> @@ -4619,22 +4651,22 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Insufficient funds</translation> </message> <message> - <location line="+14"/> + <location line="+13"/> <source>Loading block index...</source> <translation>Loading block index...</translation> </message> <message> - <location line="-63"/> + <location line="-60"/> <source>Add a node to connect to and attempt to keep the connection open</source> <translation>Add a node to connect to and attempt to keep the connection open</translation> </message> <message> - <location line="+64"/> + <location line="+61"/> <source>Loading wallet...</source> <translation>Loading wallet...</translation> </message> <message> - <location line="-57"/> + <location line="-56"/> <source>Cannot downgrade wallet</source> <translation>Cannot downgrade wallet</translation> </message> @@ -4644,17 +4676,17 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Cannot write default address</translation> </message> <message> - <location line="+77"/> + <location line="+74"/> <source>Rescanning...</source> <translation>Rescanning...</translation> </message> <message> - <location line="-64"/> + <location line="-63"/> <source>Done loading</source> <translation>Done loading</translation> </message> <message> - <location line="+9"/> + <location line="+13"/> <source>Error</source> <translation>Error</translation> </message> diff --git a/src/qt/locale/bitcoin_eo.ts b/src/qt/locale/bitcoin_eo.ts index e84dac6b1e..17ce494f91 100644 --- a/src/qt/locale/bitcoin_eo.ts +++ b/src/qt/locale/bitcoin_eo.ts @@ -1,7 +1,11 @@ -<TS language="eo" version="2.1"> +<TS language="eo" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Dekstre-klaku por redakti adreson aŭ etikedon</translation> + </message> + <message> <source>Create a new address</source> <translation>Krei novan adreson</translation> </message> @@ -31,7 +35,7 @@ </message> <message> <source>Export the data in the current tab to a file</source> - <translation>Eksporti al dosiero la datumojn el la aktuala langeto</translation> + <translation>Eksporti la datumojn el la aktuala langeto al dosiero</translation> </message> <message> <source>&Export</source> @@ -89,7 +93,11 @@ <source>Exporting Failed</source> <translation>ekspotado malsukcesinta</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Okazis eraron dum konservo de adreslisto al %1. Bonvolu provi denove.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -148,10 +156,6 @@ <translation>Ŝanĝi la pasfrazon</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Tajpu la malnovan kaj novan monujajn pasfrazojn.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Konfirmo de ĉifrado de la monujo</translation> </message> @@ -176,10 +180,6 @@ <translation>La monujo estas ĉifrita</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitmono nun fermiĝos por fini la ĉifradon. Memoru, ke eĉ ĉifrado ne protektas kontraŭ ĉiu atako, ekz. se viruso infektus vian komputilon.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>Ĉifrado de la monujo fiaskis</translation> </message> @@ -299,10 +299,6 @@ <translation>Sendi monon al Bitmon-adreso</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Modifi agordaĵojn por Bitmono</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Krei alilokan sekurkopion de monujo</translation> </message> @@ -339,6 +335,10 @@ <translation>&Ricevi</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>Vidigi informon pri Bitmona Kerno</translation> + </message> + <message> <source>&Show / Hide</source> <translation>&Montri / Kaŝi</translation> </message> @@ -402,34 +402,14 @@ <source>&Command-line options</source> <translation>&Komandliniaj agordaĵoj</translation> </message> - <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n aktiva konekto al la bitmona reto</numerusform><numerusform>%n aktivaj konektoj al la bitmona reto</numerusform></translation> - </message> <message> <source>No block source available...</source> <translation>Neniu fonto de blokoj trovebla...</translation> </message> - <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n horo</numerusform><numerusform>%n horoj</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n tago</numerusform><numerusform>%n tagoj</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n week(s)</source> - <translation><numerusform>%n semajno</numerusform><numerusform>%n semajnoj</numerusform></translation> - </message> <message> <source>%1 and %2</source> <translation>%1 kaj %2</translation> </message> - <message numerus="yes"> - <source>%n year(s)</source> - <translation><numerusform>%n jaro</numerusform><numerusform>%n jaroj</numerusform></translation> - </message> <message> <source>%1 behind</source> <translation>mankas %1</translation> @@ -471,18 +451,6 @@ <translation>Envenanta transakcio</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Dato: %1 -Sumo: %2 -Tipo: %3 -Adreso: %4 -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Monujo estas <b>ĉifrita</b> kaj aktuale <b>malŝlosita</b></translation> </message> @@ -521,6 +489,10 @@ Adreso: %4 <translation>Krompago:</translation> </message> <message> + <source>Dust:</source> + <translation>Polvo:</translation> + </message> + <message> <source>After Fee:</source> <translation>Post krompago:</translation> </message> @@ -545,6 +517,14 @@ Adreso: %4 <translation>Sumo</translation> </message> <message> + <source>Received with label</source> + <translation>Ricevita kun etikedo</translation> + </message> + <message> + <source>Received with address</source> + <translation>Ricevita kun adreso</translation> + </message> + <message> <source>Date</source> <translation>Dato</translation> </message> @@ -605,6 +585,10 @@ Adreso: %4 <translation>Kopii prioritaton</translation> </message> <message> + <source>Copy dust</source> + <translation>Kopii polvon</translation> + </message> + <message> <source>Copy change</source> <translation>Kopii restmonon</translation> </message> @@ -661,10 +645,6 @@ Adreso: %4 <translation>ne</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Tiu ĉi etikedo ruĝiĝas se la grando de la transakcio estas pli ol 1000 bajtoj.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Tio signifas, ke krompago de almenaŭ po %1 por ĉiu kB estas deviga.</translation> </message> @@ -677,10 +657,6 @@ Adreso: %4 <translation>Transakcioj kun pli alta prioritato havas pli altan ŝancon inkluziviĝi en bloko.</translation> </message> <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Tiu ĉi etikedo ruĝiĝas se iu ajn ricevonto ricevos sumon malpli ol %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(neniu etikedo)</translation> </message> @@ -797,26 +773,6 @@ Adreso: %4 <source>command-line options</source> <translation>komandliniaj agordaĵoj</translation> </message> - <message> - <source>UI options</source> - <translation>UI-agordaĵoj</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Agordi lingvon, ekzemple "de_DE" (defaŭlte: tiu de la sistemo)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Lanĉiĝi plejete</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Montri salutŝildon dum lanĉo (defaŭlte: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Elekti dosierujon por datumoj dum lanĉo (defaŭlte: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -887,14 +843,6 @@ Adreso: %4 <translation>Ĉ&efa</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Aŭtomate lanĉi Bitmonon post ensaluto al la sistemo.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Lanĉi Bitmonon tuj post ensaluto al la sistemo</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Dosiergrando de &datumbasa kaŝmemoro</translation> </message> @@ -915,6 +863,10 @@ Adreso: %4 <translation>&Reto</translation> </message> <message> + <source>Expert</source> + <translation>Fakulo</translation> + </message> + <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> <translation>Aŭtomate malfermi la kursilan pordon por Bitmono. Tio funkcias nur se via kursilo havas la UPnP-funkcion, kaj se tiu ĉi estas ŝaltita.</translation> </message> @@ -947,10 +899,6 @@ Adreso: %4 <translation>&Minimumigi al la sistempleto anstataŭ al la taskopleto</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimumigi la aplikaĵon anstataŭ eliri kaj ĉesi kiam la fenestro estas fermita. Se tiu ĉi estas agordita, la aplikaĵo ĉesas nur kiam oni elektas "Eliri" el la menuo.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimumigi je fermo</translation> </message> @@ -963,10 +911,6 @@ Adreso: %4 <translation>&Lingvo de la fasado:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Vi povas elekti la lingvon uzata en la aplikaĵo ĉi tie. Tiu ekefikos nur post relanĉo de Bitmono.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Unuo por vidigi sumojn:</translation> </message> @@ -1037,11 +981,7 @@ Adreso: %4 <source>Your current total balance</source> <translation>via aktuala totala saldo</translation> </message> - <message> - <source>out of sync</source> - <translation>nesinkronigita</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> <message> @@ -1181,6 +1121,10 @@ Adreso: %4 <translation>Aktuala nombro de blokoj</translation> </message> <message> + <source>Bytes Sent</source> + <translation>Bajtoj Senditaj:</translation> + </message> + <message> <source>Last block time</source> <translation>Horo de la lasta bloko</translation> </message> @@ -1221,18 +1165,10 @@ Adreso: %4 <translation>Sencimiga protokoldosiero</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Malfermi la sencimiga protokoldosiero de Bitmono el la aktuala dosierujo por datumoj. Tio eble daŭros plurajn sekundojn por granda protokoldosiero.</translation> - </message> - <message> <source>Clear console</source> <translation>Malplenigi konzolon</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Bonvenon al la RPC-konzolo de Bitmono.</translation> - </message> - <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Uzu la sagojn supran kaj malsupran por esplori la historion, kaj <b>stir-L</b> por malplenigi la ekranon.</translation> </message> @@ -1398,7 +1334,7 @@ Adreso: %4 <name>SendCoinsDialog</name> <message> <source>Send Coins</source> - <translation>Sendi Monon</translation> + <translation>Sendi Bitmonon</translation> </message> <message> <source>Coin Control Features</source> @@ -1453,8 +1389,12 @@ Adreso: %4 <translation>Malplenigi ĉiujn kampojn de la formularo.</translation> </message> <message> + <source>Dust:</source> + <translation>Polvo:</translation> + </message> + <message> <source>Clear &All</source> - <translation>&Forigi ĉion</translation> + <translation>&Forigi Ĉion</translation> </message> <message> <source>Balance:</source> @@ -1513,10 +1453,6 @@ Adreso: %4 <translation>aŭ</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>La adreso de la ricevonto ne validas. Bonvolu kontroli.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>La pagenda sumo devas esti pli ol 0.</translation> </message> @@ -1529,10 +1465,6 @@ Adreso: %4 <translation>La sumo kun la %1 krompago estas pli granda ol via saldo.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Iu adreso estas ripetita. Vi povas sendi al ĉiu adreso po unufoje en iu send-operacio.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Kreo de transakcio fiaskis!</translation> </message> @@ -1545,6 +1477,10 @@ Adreso: %4 <translation>(neniu etikedo)</translation> </message> <message> + <source>Copy dust</source> + <translation>Kopii polvon</translation> + </message> + <message> <source>Are you sure you want to send?</source> <translation>Ĉu vi certas, ke vi volas sendi?</translation> </message> @@ -1585,7 +1521,7 @@ Adreso: %4 </message> <message> <source>Paste address from clipboard</source> - <translation>Alglui adreson el tondejo</translation> + <translation>Alglui adreson de tondejo</translation> </message> <message> <source>Alt+P</source> @@ -1630,10 +1566,6 @@ Adreso: %4 <translation>&Subskribi Mesaĝon</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Vi povas subskribi mesaĝon per viaj adresoj, por pravigi ke vi estas la posedanto de tiuj adresoj. Atentu, ke vi ne subskriu ion neprecizan, ĉar trompisto povus ruzi kontraŭ vi kaj ŝteli vian identecon. Subskribu nur plene detaligitaj deklaroj pri kiuj vi konsentas.</translation> - </message> - <message> <source>Choose previously used address</source> <translation>Elektu la jam uzitan adreson</translation> </message> @@ -1682,10 +1614,6 @@ Adreso: %4 <translation>&Kontroli Mesaĝon</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Enmeti la subskriban adreson, la mesaĝon (kune kun ĉiu linisalto, spaceto, taboj, ktp. precize) kaj la subskribon ĉi sube por kontroli la mesaĝon. Atentu, ke vi ne komprenu per la subskribo pli ol la enhavo de la mesaĝo mem, por eviti homo-en-la-mezo-atakon.</translation> - </message> - <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>Kontroli la mesaĝon por pravigi, ke ĝi ja estas subskribita per la specifa Bitmon-adreso</translation> </message> @@ -1794,10 +1722,6 @@ Adreso: %4 <source>Status</source> <translation>Stato</translation> </message> - <message numerus="yes"> - <source>, broadcast through %n node(s)</source> - <translation><numerusform>, elsendita(j) tra %n nodo</numerusform><numerusform>, elsendita(j) tra %n nodoj</numerusform></translation> - </message> <message> <source>Date</source> <translation>Dato</translation> @@ -1830,10 +1754,6 @@ Adreso: %4 <source>Credit</source> <translation>Kredito</translation> </message> - <message numerus="yes"> - <source>matures in %n more block(s)</source> - <translation><numerusform>maturiĝos post %n bloko</numerusform><numerusform>maturiĝos post %n blokoj</numerusform></translation> - </message> <message> <source>not accepted</source> <translation>ne akceptita</translation> @@ -1898,10 +1818,6 @@ Adreso: %4 <source>, has not been successfully broadcast yet</source> <translation>, ankoraŭ ne elsendita sukcese</translation> </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>Malferma dum ankoraŭ %n bloko</numerusform><numerusform>Malferma dum ankoraŭ %n blokoj</numerusform></translation> - </message> <message> <source>unknown</source> <translation>nekonata</translation> @@ -1929,14 +1845,6 @@ Adreso: %4 <translation>Tipo</translation> </message> <message> - <source>Address</source> - <translation>Adreso</translation> - </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>Malferma dum ankoraŭ %n bloko</numerusform><numerusform>Malferma dum ankoraŭ %n blokoj</numerusform></translation> - </message> - <message> <source>Open until %1</source> <translation>Malferma ĝis %1</translation> </message> @@ -1957,6 +1865,10 @@ Adreso: %4 <translation>Senkonekte</translation> </message> <message> + <source>Label</source> + <translation>Etikedo</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Nekonfirmita</translation> </message> @@ -1997,10 +1909,6 @@ Adreso: %4 <translation>Tipo de transakcio.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Celadreso de la transakcio.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Sumo elprenita de aŭ aldonita al la saldo.</translation> </message> @@ -2255,10 +2163,6 @@ Adreso: %4 <translation>Difektita blokdatumbazo trovita</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Malkovri la propran IP-adreson (defaŭlte: 1 dum aŭskultado sen -externalip)</translation> - </message> - <message> <source>Do you want to rebuild the block database now?</source> <translation>Ĉu vi volas rekonstrui la blokdatumbazon nun?</translation> </message> @@ -2299,10 +2203,6 @@ Adreso: %4 <translation>Nesufiĉa nombro de dosierpriskribiloj disponeblas.</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Rekontrui blokĉenan indekson el la aktualaj blk000??.dat dosieroj</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Specifi monujan dosieron (ene de dosierujo por datumoj)</translation> </message> @@ -2335,6 +2235,10 @@ Adreso: %4 <translation>Plenumi komandon kiam rilata alerto riceviĝas, aŭ kiam ni vidas tre longan forkon (%s en cms anstataŭiĝas per mesaĝo)</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Elekti dosierujon por datumoj dum lanĉo (defaŭlte: 0)</translation> + </message> + <message> <source>Information</source> <translation>Informoj</translation> </message> @@ -2351,6 +2255,14 @@ Adreso: %4 <translation>Sendi spurajn/sencimigajn informojn al la konzolo anstataŭ al dosiero debug.log</translation> </message> <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Agordi lingvon, ekzemple "de_DE" (defaŭlte: tiu de la sistemo)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Montri salutŝildon dum lanĉo (defaŭlte: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Malpligrandigi la sencimigan protokol-dosieron kiam kliento lanĉiĝas (defaŭlte: 1 kiam mankas -debug)</translation> </message> @@ -2359,6 +2271,10 @@ Adreso: %4 <translation>Subskriba transakcio fiaskis</translation> </message> <message> + <source>Start minimized</source> + <translation>Lanĉiĝi plejete</translation> + </message> + <message> <source>This is experimental software.</source> <translation>ĝi estas eksperimenta programo</translation> </message> @@ -2387,10 +2303,6 @@ Adreso: %4 <translation>Averto</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Averto: tiu ĉi versio estas eksdata. Vi bezonas ĝisdatigon!</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat estas difektita, riparo malsukcesis</translation> </message> diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index e52bf88a87..de55496c09 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -1,9 +1,9 @@ -<TS language="es" version="2.1"> +<TS language="es" version="2.0"> <context> <name>AddressBookPage</name> <message> <source>Right-click to edit address or label</source> - <translation>Haz-clic para editar la dirección o etiqueta</translation> + <translation>Haz clic derecho para editar la dirección o etiqueta</translation> </message> <message> <source>Create a new address</source> @@ -31,7 +31,7 @@ </message> <message> <source>Delete the currently selected address from the list</source> - <translation>Borrar de la lista la dirección seleccionada</translation> + <translation>Eliminar la dirección seleccionada de la lista</translation> </message> <message> <source>Export the data in the current tab to a file</source> @@ -47,11 +47,11 @@ </message> <message> <source>Choose the address to send coins to</source> - <translation>Elije la dirección para enviar monedas a</translation> + <translation>Elija la dirección para enviar monedas a</translation> </message> <message> <source>Choose the address to receive coins with</source> - <translation>Elije la dirección para recibir monedas con</translation> + <translation>Elija la dirección para recibir monedas con</translation> </message> <message> <source>C&hoose</source> @@ -75,7 +75,7 @@ </message> <message> <source>Copy &Label</source> - <translation>Copiar &etiqueta</translation> + <translation>Copiar &Etiqueta</translation> </message> <message> <source>&Edit</source> @@ -152,10 +152,6 @@ <translation>Cambiar contraseña</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Introduce la antigua y la nueva contraseña a el monedero.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Confirmar cifrado del monedero</translation> </message> @@ -168,6 +164,10 @@ <translation>¿Estás seguro que deseas cifrar tu monedero ?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -184,8 +184,8 @@ <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin se cerrará para finalizar el proceso de cifrado. Recuerde que el cifrado de su monedero no puede proteger totalmente sus bitcoins de robo por malware que infecte su sistema.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Introduce la antigua y la nueva contraseña de la cartera.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -307,10 +307,6 @@ <translation>Enviar bitcoins a una dirección Bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Modificar las opciones de configuración de Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Copia de seguridad del monedero en otra ubicación</translation> </message> @@ -320,7 +316,7 @@ </message> <message> <source>&Debug window</source> - <translation>Ventana de &depuración</translation> + <translation>&Ventana de depuración</translation> </message> <message> <source>Open debugging and diagnostic console</source> @@ -399,6 +395,10 @@ <translation>&Acerca de Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modificar las opciones de configuración de Bitcoin</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Mostrar la lista de direcciones de envío y etiquetas</translation> </message> @@ -427,6 +427,10 @@ <translation>Ninguna fuente de bloques disponible ...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>%n bloque procesado del historial de transacciones.</numerusform><numerusform>%n bloques procesados del historial de transacciones.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation> </message> @@ -474,35 +478,49 @@ <source>Up to date</source> <translation>Actualizado</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>%n bloques procesados del historial de transacciones</numerusform><numerusform>Procesados %n bloques del historial de transacciones</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Actualizando...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Transacción enviada</translation> + <source>Date: %1 +</source> + <translation>Fecha: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Transacción entrante</translation> + <source>Amount: %1 +</source> + <translation>Amount: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Fecha: %1 -Cantidad: %2 -Tipo: %3 -Dirección: %4 + <translation>Tipo: %1 </translation> </message> <message> + <source>Label: %1 +</source> + <translation>Etiqueta: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Dirección: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Transacción enviada</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Transacción entrante</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>El monedero está <b>cifrado</b> y actualmente <b>desbloqueado</b></translation> </message> @@ -693,6 +711,18 @@ Dirección: %4 <translation>ninguna</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Esta etiqueta se mostrará en rojo si el tamaño de la transacción es mayor de 1000 bytes.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Esta etiqueta se mostrará en rojo si la prioridad es menor a "media"</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Esta etiqueta se vuelve roja si el cambio es menor que %1</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Puede variar en +/- %1 satoshi(s) por entrada.</translation> </message> @@ -705,10 +735,6 @@ Dirección: %4 <translation>no</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Esta etiqueta se torna roja si el tamaño de la transacción es mayor de 1000 bytes.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Esto implica que se requiere una comisión de al menos %1 por kB</translation> </message> @@ -721,14 +747,6 @@ Dirección: %4 <translation>Las transacciones con mayor prioridad tienen mayor probabilidad de ser incluidas en un bloque.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Esta etiqueta se torna roja si la prioridad es menor que "media".</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Esta etiqueta se torna roja si cualquier destinatario recibe una cantidad menor de %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(sin etiqueta)</translation> </message> @@ -849,30 +867,6 @@ Dirección: %4 <source>command-line options</source> <translation>opciones de la consola de comandos</translation> </message> - <message> - <source>UI options</source> - <translation>Opciones de interfaz de usuario</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Arrancar minimizado</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Establecer los certificados raíz SSL para solicitudes de pago (predeterminado: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostrar pantalla de bienvenida en el inicio (predeterminado: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Elegir directorio de datos al iniciar (predeterminado: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -955,14 +949,6 @@ Dirección: %4 <translation>&Principal</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Iniciar Bitcoin automáticamente al encender el sistema.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Iniciar Bitcoin al iniciar el sistema</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Tamaño de cache de la &base de datos</translation> </message> @@ -987,6 +973,14 @@ Dirección: %4 <translation>Dirección IP del proxy (p. ej. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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ú.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>El idioma de la interfaz de usuario puede establecerse aquí. Este ajuste se aplicará cuando se reinicie Bitcoin.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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 |.</translation> </message> @@ -1011,6 +1005,14 @@ Dirección: %4 <translation>&Red</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Iniciar automáticamente Bitcoin Core al iniciar el sistema.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Iniciar Bitcoin Core al inicio del sistema</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = automático, <0 = dejar libres ese número de núcleos)</translation> </message> @@ -1075,10 +1077,6 @@ Dirección: %4 <translation>&Minimizar a la bandeja en vez de a la barra de tareas</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimizar en lugar de salir de la aplicación al cerrar la ventana. Cuando esta opción está activa, la aplicación solo se puede cerrar seleccionando Salir desde el menú.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimizar al cerrar</translation> </message> @@ -1091,10 +1089,6 @@ Dirección: %4 <translation>I&dioma de la interfaz de usuario</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>El idioma de la interfaz de usuario puede establecerse aquí. Este ajuste se aplicará cuando se reinicie Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>Mostrar las cantidades en la &unidad:</translation> </message> @@ -1131,7 +1125,7 @@ Dirección: %4 <translation>Se necesita reiniciar el cliente para activar los cambios.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> + <source>Client will be shut down. Do you want to proceed?</source> <translation>El cliente se cerrará. ¿Desea continuar?</translation> </message> <message> @@ -1217,10 +1211,6 @@ Dirección: %4 <source>Current total balance in watch-only addresses</source> <translation>Saldo total en las direcciones watch-only</translation> </message> - <message> - <source>out of sync</source> - <translation>desincronizado</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1241,10 +1231,6 @@ Dirección: %4 <translation>La red de solicitud de pago no coincide con la red cliente</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>La solicitud de pago ha cadiucado</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>La solicitud de pago no está inicializada</translation> </message> @@ -1277,10 +1263,18 @@ Dirección: %4 <translation>¡No puede leerse el archivo de solicitud de pago! Esto puede deberse a un archivo inválido de solicitud de pago.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Solicitud de pago caducada.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>No están soportadas las peticiones inseguras a scripts de pago personalizados</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Petición de pago no válida.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Devolución desde %1</translation> </message> @@ -1320,8 +1314,8 @@ Dirección: %4 <translation>User Agent</translation> </message> <message> - <source>Address/Hostname</source> - <translation>DIrección/Nombre de host</translation> + <source>Node/Service</source> + <translation>Nodo/Servicio</translation> </message> <message> <source>Ping Time</source> @@ -1355,14 +1349,6 @@ Dirección: %4 <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>RED</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>DESCONOCIDO</translation> - </message> - <message> <source>None</source> <translation>Ninguno</translation> </message> @@ -1453,6 +1439,10 @@ Dirección: %4 <translation>Número actual de bloques</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>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.</translation> + </message> + <message> <source>Received</source> <translation>Recibido</translation> </message> @@ -1521,6 +1511,10 @@ Dirección: %4 <translation>Ping</translation> </message> <message> + <source>Time Offset</source> + <translation>Desplazamiento de tiempo</translation> + </message> + <message> <source>Last block time</source> <translation>Hora del último bloque</translation> </message> @@ -1561,16 +1555,12 @@ Dirección: %4 <translation>Archivo de registro de depuración</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Abrir el archivo de registro de depuración en el directorio actual de datos. Esto puede llevar varios segundos para archivos de registro grandes.</translation> - </message> - <message> <source>Clear console</source> <translation>Borrar consola</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Bienvenido a la consola RPC de Bitcoin</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Bienvenido a la consola RPC de Bitcoin Core.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1861,14 +1851,6 @@ Dirección: %4 <translation>Colapsar ajustes de cuota</translation> </message> <message> - <source>Minimize</source> - <translation>Minimizar</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Si la tarifa de aduana se establece en 1000 satoshis y la transacción está a disponible a solo 250 bytes, entonces "por kilobyte" sólo paga 250 satoshis de cuota, mientras que "por lo menos" paga 1.000 satoshis. Para las transacciones más grandes que un kilobyte ambos pagan por kilobyte.</translation> - </message> - <message> <source>per kilobyte</source> <translation>por kilobyte</translation> </message> @@ -1877,6 +1859,10 @@ Dirección: %4 <translation>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</translation> </message> <message> + <source>Hide</source> + <translation>Ocultar</translation> + </message> + <message> <source>total at least</source> <translation>total por lo menos</translation> </message> @@ -1997,10 +1983,6 @@ Dirección: %4 <translation>o</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>La dirección de recepción no es válida, compruébela de nuevo.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>La cantidad por pagar tiene que ser mayor de 0.</translation> </message> @@ -2013,10 +1995,6 @@ Dirección: %4 <translation>El total sobrepasa su saldo cuando se incluye la tasa de envío de %1</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Se ha encontrado una dirección duplicada. Solo se puede enviar a cada dirección una vez por operación de envío.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>¡Ha fallado la creación de la transacción!</translation> </message> @@ -2025,12 +2003,24 @@ Dirección: %4 <translation>¡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.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Solicitud de pago caducada.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Estimado para empezar la confirmación dentro de %n bloque.</numerusform><numerusform>Estimado para empezar la confirmación dentro de %n bloques.</numerusform></translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Paga sólo la cuota mínima de %1</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Estimado para comenzar confirmación dentro de %1 bloque(s)</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>La dirección del destinatario no es válida. Por favor, compruébela de nuevo.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Se ha encontrado una dirección duplicada. Solo se puede enviar a cada dirección una vez por operación de envío.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2104,12 +2094,24 @@ Dirección: %4 <translation>Eliminar esta transacción</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>La cuota será deducida de la cantidad que sea mandada. El destinatario recibirá menos bitcoins de los que entres en el </translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>Restar comisiones a la cantidad</translation> + </message> + <message> <source>Message:</source> <translation>Mensaje:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Esto es una petición de pago verificado.</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Esta es una petición de pago no autentificada.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Esta es una petición de pago autentificada.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2120,10 +2122,6 @@ Dirección: %4 <translation>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.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Esto es una petición de pago no verificado.</translation> - </message> - <message> <source>Pay To:</source> <translation>Paga a:</translation> </message> @@ -2154,8 +2152,8 @@ Dirección: %4 <translation>&Firmar mensaje</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Puede firmar mensajes con sus direcciones para demostrar que las posee. Tenga cuidado de no firmar cualquier cosa vaga, ya que los ataques de phishing pueden tratar de engañarle para suplantar su identidad. Firme solo declaraciones totalmente detalladas con las que usted esté de acuerdo.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>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.</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2210,8 +2208,8 @@ Dirección: %4 <translation>&Verificar mensaje</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>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.</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>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. </translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2477,10 +2475,6 @@ Dirección: %4 <translation>Tipo</translation> </message> <message> - <source>Address</source> - <translation>Dirección</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>No vencidos (%1 confirmaciones. Estarán disponibles al cabo de %2)</translation> </message> @@ -2509,6 +2503,10 @@ Dirección: %4 <translation>Sin conexión</translation> </message> <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Sin confirmar</translation> </message> @@ -2565,8 +2563,8 @@ Dirección: %4 <translation>Sea o no una dirección sólo está involucrada en esta transacción.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Dirección de destino de la transacción.</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>intento/propósito de la transacción definido por el usuario.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2823,16 +2821,16 @@ Dirección: %4 <translation>Distribuido bajo la licencia de software MIT, vea la copia del archivo adjunto o <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Ingresar en el modo de prueba de regresión, que utiliza una cadena especial en la que los bloques se pueden resolver instantáneamente.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Ejecutar comando cuando una transacción del monedero cambia (%s en cmd se remplazará por TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>En este modo -genproclimit controla cuántos bloques se generan de inmediato.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Maximo Comisión totales para usar en una sola transacción billetera; establecer esta demasiado bajo puede abortar transacciones grandes (por defecto: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Reducir los requerimientos de almacenamiento mediante la poda (borrado) bloquea viejos. Este modo desactiva el apoyo cartera y es incompatible con -txindex. Advertencia: Revertir esta configuración requiere volver a descargar toda la blockchain. (por defecto: 0 = desactivar bloques de poda, >%u = tamaño de destino en MiB de usar para los archivos de bloques)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2847,6 +2845,14 @@ Dirección: %4 <translation>No se ha podido acceder a %s en esta máquina. Probablemente ya se está ejecutando Bitcoin Core.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>ADVERTENCIA: anormalmente alto número de bloques generado, %d bloques recibidos en las últimas horas %d (%d espera)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>ADVERTENCIA: comprueba tu conexión de red, %d bloques recibidos en las últimas %d horas (%d esperados)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Aviso: ¡-paytxfee tiene un valor muy alto! Esta es la comisión que pagará si envía una transacción.</translation> </message> @@ -2903,10 +2909,6 @@ Dirección: %4 <translation>Opciones de depuración/pruebas:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Descubrir dirección IP propia (predeterminado: 1 al escuchar sin -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>No cargar el monedero y desactivar las llamadas RPC del monedero</translation> </message> @@ -2967,8 +2969,12 @@ Dirección: %4 <translation>Sólo conectar a nodos en redes <net> (ipv4, ipv6 o onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Reconstruir el índice de la cadena de bloques a partir de los archivos blk000??.dat actuales</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>Pode no se puede configurar con un valor negativo.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>El modo recorte es incompatible con -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2983,10 +2989,6 @@ Dirección: %4 <translation>Especificar archivo de monedero (dentro del directorio de datos)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Esto afecta a las herramientas de prueba de regresión y al desarrollo informático de la aplicación.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Usar UPnP para asignar el puerto de escucha (predeterminado:: %u)</translation> </message> @@ -3007,6 +3009,10 @@ Dirección: %4 <translation>Opciones de monedero:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Peligro: Esta versión es obsoleta; actualización requerida!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Usted necesita reconstruir la base de datos utilizando -reindex para cambiar -txindex</translation> </message> @@ -3035,14 +3041,14 @@ Dirección: %4 <translation>No se ha podido bloquear el directorio de datos %s. Probablemente ya se está ejecutando Bitcoin Core.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Limitar continuamente las transacciones gratuitas a <n>*1000 bytes por minuto (predeterminado:%u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>Crear nuevos archivos con permisos por defecto del sistema, en lugar de umask 077 (sólo efectivo con la funcionalidad de monedero desactivada)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Descubra direcciones IP propias (por defecto: 1 cuando se escucha y nadie -externalip o -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Error: la escucha para conexiones entrantes falló (la escucha regresó el error %s)</translation> </message> @@ -3059,10 +3065,6 @@ Dirección: %4 <translation>Tarifas (en BTC/Kb) más pequeños que esto se consideran cero cuota de reinstalación (por defecto: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Tarifas (en BTC/Kb) más pequeños que esto se consideran cero cuota para la creación de la transacción (por defecto: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>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)</translation> </message> @@ -3071,12 +3073,16 @@ Dirección: %4 <translation>El tamaño máximo de los datos en las operaciones de transporte de datos que transmitimos y el mio (default: %u)</translation> </message> <message> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Pode configurado por debajo del mínimo de %d MB. Por favor, use un número más alto.</translation> + </message> + <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Consulta de direcciones pares mediante búsqueda de DNS, si bajo en direcciones (por defecto: 1 a menos que - conectar)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>Se requiere alta prioridad para retransmitir transacciones gratis o de baja comisión (por defecto:%u)</translation> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Aleatorizar las credenciales para cada conexión proxy. Esto habilita la Tor stream isolation (por defecto: %u)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3087,6 +3093,10 @@ Dirección: %4 <translation>Ajuste el número de hilos para la generación de moneda si está habilitado (-1 = all cores, default: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Monto de transacción muy pequeña luego de la deducción por comisión</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -3127,14 +3137,34 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>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.</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Necesitas reconstruir la base de datos utilizando -reindex para volver al modo sin recorte. Esto volverá a descargar toda la cadena de bloques</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(por defecto: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Aceptar solicitudes públicas en FERIADOS (por defecto: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Activando la mejor cadena...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>No se puede ejecutar con un monedero en modo recorte.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>No se puede resolver -whitebind address: '%s'</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Elegir directorio de datos al iniciar (predeterminado: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Conectar usando SOCKS5 proxy</translation> </message> @@ -3215,12 +3245,12 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Soporte RPC para conexiones HTTP persistentes (por defecto: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Ignorar 1 de cada <n> mensajes de red al azar</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Reconstruir el índice de la cadena de bloques en el arranque desde los actuales ficheros blk000??.dat</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Introducir datos fuzz en 1 de cada <n> mensajes de red al azar</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Recibir y mostrar alertas de red P2P (default: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3231,10 +3261,22 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Mandar transacciones como comisión-cero si es posible (por defecto: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Establecer los certificados raíz SSL para solicitudes de pago (predeterminado: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Muestra todas las opciones de depuración (uso: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Mostrar pantalla de bienvenida en el inicio (predeterminado: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Reducir el archivo debug.log al iniciar el cliente (predeterminado: 1 sin -debug)</translation> </message> @@ -3243,6 +3285,14 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Transacción falló</translation> </message> <message> + <source>Start minimized</source> + <translation>Arrancar minimizado</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Cantidad de la transacción demasiado pequeña para pagar la comisión</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Este software es experimental.</translation> </message> @@ -3263,6 +3313,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Transacción demasiado grande</translation> </message> <message> + <source>UI Options:</source> + <translation>Opciones de interfaz de usuario</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>No es posible conectar con %s en este sistema (bind ha dado el error %s)</translation> </message> @@ -3284,10 +3338,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Aviso</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Aviso: Esta versión es obsoleta, actualización necesaria!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Advertencia: Argumento no soportado -benchmark ignored, use -debug=bench.</translation> </message> @@ -3351,18 +3401,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Volcar la actividad de la base de datos de memoria al registro en disco cada <n> megabytes (predeterminado: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Nivel de rigor en la verificación de bloques de -checkblocks (0-4; predeterminado: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Registrar prioridad de las transacciones y cuota por kB cuando se minen bloques (por defecto: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Mantener el índice completo de transacciones, usado por la llamada rpc de getrawtransaction (por defecto: %u)</translation> </message> @@ -3391,18 +3433,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Siempre consultar direcciones de otros equipos por medio de DNS lookup (por defecto: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Inhabilitar el modo seguro, no considerar un suceso real de modo seguro (predeterminado: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Error al cargar wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Forzar modo seguro (por defecto: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Generar monedas (por defecto: %u)</translation> </message> @@ -3419,10 +3453,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Dirección -proxy inválida: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Limitar tamaño de la cache de firmas a <n> entradas (predeterminado: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Escuchar conexiones JSON-RPC en <puerto> (predeterminado: %u o testnet: %u)</translation> </message> @@ -3435,6 +3465,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Mantener como máximo <n> conexiones a pares (predeterminado: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Realiza las operaciones de difusión del monedero</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Búfer de recepción máximo por conexión, <n>*1000 bytes (por defecto: %u)</translation> </message> @@ -3443,10 +3477,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Búfer de recepción máximo por conexión, , <n>*1000 bytes (por defecto: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Aceptar solamente cadena de bloques que concuerde con los puntos de control internos (predeterminado: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Anteponer marca temporal a la información de depuración (por defecto: %u)</translation> </message> @@ -3459,10 +3489,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Relay non-P2SH multisig (default: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Ejecutar un hilo para limpiar de la memoria el monedero periódicamente (predeterminado: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Archivo de certificado del servidor (por defecto: %s)</translation> </message> @@ -3483,10 +3509,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Establecer el número de procesos para llamadas del servicio RPC (por defecto: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Establece la opción DB_PRIVATE en el entorno de base de datos del monedero (predeterminado: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Especificar archivo de configuración (por defecto: %s)</translation> </message> @@ -3503,10 +3525,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Gastar cambio no confirmado al enviar transacciones (predeterminado: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Detener después de importar los bloques del disco (por defecto: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Umbral para la desconexión de pares con mal comportamiento (predeterminado: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts index 4495d9bd50..c35acf2c67 100644 --- a/src/qt/locale/bitcoin_es_CL.ts +++ b/src/qt/locale/bitcoin_es_CL.ts @@ -1,4 +1,4 @@ -<TS language="es_CL" version="2.1"> +<TS language="es_CL" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -112,10 +112,6 @@ <translation>Cambia contraseña</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Introduce la contraseña anterior y la nueva de cartera</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Confirma la codificación de cartera</translation> </message> @@ -140,10 +136,6 @@ <translation>Billetera codificada</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin se cerrará para finalizar el proceso de encriptación. Recuerde que encriptar su billetera no protegera completatamente sus bitcoins de ser robados por malware que infecte su computador</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>Falló la codificación de la billetera</translation> </message> @@ -212,7 +204,7 @@ </message> <message> <source>Show information about Qt</source> - <translation>Mostrar Información sobre QT</translation> + <translation>Mostrar Información sobre Qt</translation> </message> <message> <source>&Options...</source> @@ -247,10 +239,6 @@ <translation>Enviar monedas a una dirección bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Modifica las opciones de configuración de bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Respaldar billetera en otra ubicación</translation> </message> @@ -310,22 +298,6 @@ <source>Bitcoin Core</source> <translation>bitcoin core</translation> </message> - <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n conexión activa hacia la red Bitcoin</numerusform><numerusform>%n conexiones activas hacia la red Bitcoin</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n día</numerusform><numerusform>%n días</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n week(s)</source> - <translation><numerusform>%n semana</numerusform><numerusform>%n semanas</numerusform></translation> - </message> <message> <source>Error</source> <translation>Error</translation> @@ -355,17 +327,6 @@ <translation>Transacción entrante</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Fecha: %1 -Cantidad: %2 -Tipo: %3 -Dirección: %4</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>La billetera esta <b>codificada</b> y actualmente <b>desbloqueda</b></translation> </message> @@ -500,15 +461,6 @@ Dirección: %4</translation> <source>Usage:</source> <translation>Uso:</translation> </message> - <message> - <source>UI options</source> - <translation>UI opciones</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Arranca minimizado -</translation> - </message> </context> <context> <name>Intro</name> @@ -543,14 +495,6 @@ Dirección: %4</translation> <translation>&Principal</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Inicia Bitcoin automáticamente despues de encender el computador</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Inicia Bitcoin al iniciar el sistema</translation> - </message> - <message> <source>Reset all client options to default.</source> <translation>Reestablece todas las opciones.</translation> </message> @@ -596,10 +540,6 @@ Dirección: %4</translation> <translation>&Minimiza a la bandeja en vez de la barra de tareas</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimiza la ventana en lugar de salir del programa cuando la ventana se cierra. Cuando esta opción esta activa el programa solo se puede cerrar seleccionando Salir desde el menu.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimiza a la bandeja al cerrar</translation> </message> @@ -642,11 +582,7 @@ Dirección: %4</translation> <source>Total:</source> <translation>Total:</translation> </message> - <message> - <source>out of sync</source> - <translation>desincronizado</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> <message> @@ -664,10 +600,6 @@ Dirección: %4</translation> <translation>Cantidad</translation> </message> <message> - <source>UNKNOWN</source> - <translation>DESCONOCIDO</translation> - </message> - <message> <source>N/A</source> <translation>N/A</translation> </message> @@ -863,10 +795,6 @@ Dirección: %4</translation> <translation>Copiar Cantidad</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>La dirección de destinatarion no es valida, comprueba otra vez.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>La cantidad por pagar tiene que ser mayor 0.</translation> </message> @@ -879,10 +807,6 @@ Dirección: %4</translation> <translation>El total sobrepasa tu saldo cuando se incluyen %1 como tasa de envio.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Tienes una dirección duplicada, solo puedes enviar a direcciónes individuales de una sola vez.</translation> - </message> - <message> <source>(no label)</source> <translation>(sin etiqueta)</translation> </message> @@ -1104,10 +1028,6 @@ Dirección: %4</translation> <source>, has not been successfully broadcast yet</source> <translation>, no ha sido emitido satisfactoriamente todavía</translation> </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>Abierto para %n bloque más</numerusform><numerusform>Abierto para %n bloques más</numerusform></translation> - </message> <message> <source>unknown</source> <translation>desconocido</translation> @@ -1135,10 +1055,6 @@ Dirección: %4</translation> <translation>Tipo</translation> </message> <message> - <source>Address</source> - <translation>Dirección</translation> - </message> - <message> <source>Open until %1</source> <translation>Abierto hasta %1</translation> </message> @@ -1155,6 +1071,10 @@ Dirección: %4</translation> <translation>Generado pero no acceptado</translation> </message> <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + <message> <source>Received with</source> <translation>Recibido con</translation> </message> @@ -1191,10 +1111,6 @@ Dirección: %4</translation> <translation>Tipo de transacción.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Dirección de destino para la transacción</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Cantidad restada o añadida al balance</translation> </message> @@ -1407,6 +1323,11 @@ Dirección: %4</translation> <translation>Enviar informacion de seguimiento a la consola en vez del archivo debug.log</translation> </message> <message> + <source>Start minimized</source> + <translation>Arranca minimizado +</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Intenta usar UPnP para mapear el puerto de escucha (default: 1 when listening)</translation> </message> @@ -1420,10 +1341,6 @@ Dirección: %4</translation> <translation>Atención</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Advertencia: Esta versión está obsoleta, se necesita actualizar!</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat corrompió, guardado fallido</translation> </message> diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts index 1c881fcf64..6071702989 100644 --- a/src/qt/locale/bitcoin_es_DO.ts +++ b/src/qt/locale/bitcoin_es_DO.ts @@ -1,4 +1,4 @@ -<TS language="es_DO" version="2.1"> +<TS language="es_DO" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -148,10 +148,6 @@ <translation>Cambiar contraseña</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Introduzca la contraseña anterior de la cartera y la nueva. </translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Confirmar cifrado de la cartera</translation> </message> @@ -176,10 +172,6 @@ <translation>Monedero cifrado</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin se cerrará para finalizar el proceso de cifrado. Recuerde que el cifrado de su monedero no puede proteger totalmente sus bitcoins de robo por malware que infecte su sistema.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>Ha fallado el cifrado del monedero</translation> </message> @@ -295,10 +287,6 @@ <translation>Enviar monedas a una dirección Bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Modificar las opciones de configuración de Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Copia de seguridad del monedero en otra ubicación</translation> </message> @@ -443,18 +431,6 @@ <translation>Transacción entrante</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Fecha: %1 -Cantidad: %2 -Tipo: %3 -Dirección: %4 -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>El monedero está <b>cifrado</b> y actualmente <b>desbloqueado</b></translation> </message> @@ -633,10 +609,6 @@ Dirección: %4 <translation>no</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Esta etiqueta se torna roja si el tamaño de la transación es mayor a 1000 bytes.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Esto implica que se requiere una tarifa de al menos %1 por kB</translation> </message> @@ -649,14 +621,6 @@ Dirección: %4 <translation>Las transacciones con alta prioridad son más propensas a ser incluidas dentro de un bloque.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Esta etiqueta se convierte en rojo, si la prioridad es menor que "medio".</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Esta etiqueta se torna roja si cualquier destinatario recibe una cantidad menor a %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(sin etiqueta)</translation> </message> @@ -773,26 +737,6 @@ Dirección: %4 <source>command-line options</source> <translation>opciones de la línea de órdenes</translation> </message> - <message> - <source>UI options</source> - <translation>Opciones GUI</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Arrancar minimizado</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostrar pantalla de bienvenida en el inicio (predeterminado: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Elegir directorio de datos al iniciar (predeterminado: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -863,14 +807,6 @@ Dirección: %4 <translation>&Principal</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Iniciar Bitcoin automáticamente al encender el sistema.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Iniciar Bitcoin al iniciar el sistema</translation> - </message> - <message> <source>MB</source> <translation>MB</translation> </message> @@ -927,10 +863,6 @@ Dirección: %4 <translation>&Minimizar a la bandeja en vez de a la barra de tareas</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimizar en lugar de salir de la aplicación al cerrar la ventana. Cuando esta opción está activa, la aplicación solo se puede cerrar seleccionando Salir desde el menú.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimizar al cerrar</translation> </message> @@ -943,10 +875,6 @@ Dirección: %4 <translation>I&dioma de la interfaz de usuario</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>El idioma de la interfaz de usuario puede establecerse aquí. Este ajuste se aplicará cuando se reinicie Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>Mostrar las cantidades en la &unidad:</translation> </message> @@ -1025,11 +953,7 @@ Dirección: %4 <source>Your current total balance</source> <translation>Su balance actual total</translation> </message> - <message> - <source>out of sync</source> - <translation>desincronizado</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> <message> @@ -1213,18 +1137,10 @@ Dirección: %4 <translation>Archivo de registro de depuración</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Abrir el archivo de registro de depuración en el directorio actual de datos. Esto puede llevar varios segundos para archivos de registro grandes.</translation> - </message> - <message> <source>Clear console</source> <translation>Borrar consola</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Bienvenido a la consola RPC de Bitcoin</translation> - </message> - <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Use las flechas arriba y abajo para navegar por el historial y <b>Control+L</b> para limpiar la pantalla.</translation> </message> @@ -1521,10 +1437,6 @@ Dirección: %4 <translation>o</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>La dirección de recepción no es válida, compruébela de nuevo.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>La cantidad por pagar tiene que ser mayor de 0.</translation> </message> @@ -1537,10 +1449,6 @@ Dirección: %4 <translation>El total sobrepasa su saldo cuando se incluye la tasa de envío de %1</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Se ha encontrado una dirección duplicada. Solo se puede enviar a cada dirección una vez por operación de envío.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>¡Ha fallado la creación de la transacción!</translation> </message> @@ -1612,18 +1520,10 @@ Dirección: %4 <translation>Eliminar esta transacción</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Esto es una petición de pago verificado.</translation> - </message> - <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Introduce una etiqueta para esta dirección para añadirla a la lista de direcciones utilizadas</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Esto es una petición de pago no verificado.</translation> - </message> - <message> <source>Pay To:</source> <translation>Paga a:</translation> </message> @@ -1646,10 +1546,6 @@ Dirección: %4 <translation>&Firmar mensaje</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Puede firmar mensajes con sus direcciones para demostrar que las posee. Tenga cuidado de no firmar cualquier cosa vaga, ya que los ataques de phishing pueden tratar de engañarle para suplantar su identidad. Firme solo declaraciones totalmente detalladas con las que usted esté de acuerdo.</translation> - </message> - <message> <source>Choose previously used address</source> <translation>Escoger dirección previamente usada</translation> </message> @@ -1698,10 +1594,6 @@ Dirección: %4 <translation>&Verificar mensaje</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>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.</translation> - </message> - <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>Verificar el mensaje para comprobar que fue firmado con la dirección Bitcoin indicada</translation> </message> @@ -1933,10 +1825,6 @@ Dirección: %4 <translation>Tipo</translation> </message> <message> - <source>Address</source> - <translation>Dirección</translation> - </message> - <message> <source>Open until %1</source> <translation>Abierto hasta %1</translation> </message> @@ -1953,6 +1841,10 @@ Dirección: %4 <translation>Generado pero no aceptado</translation> </message> <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + <message> <source>Received with</source> <translation>Recibido con</translation> </message> @@ -1989,10 +1881,6 @@ Dirección: %4 <translation>Tipo de transacción.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Dirección de destino de la transacción.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Cantidad retirada o añadida al saldo.</translation> </message> @@ -2279,10 +2167,6 @@ Dirección: %4 <translation>Corrupción de base de datos de bloques detectada.</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Descubrir dirección IP propia (predeterminado: 1 al escuchar sin -externalip)</translation> - </message> - <message> <source>Do you want to rebuild the block database now?</source> <translation>¿Quieres reconstruir la base de datos de bloques ahora?</translation> </message> @@ -2327,10 +2211,6 @@ Dirección: %4 <translation>No hay suficientes descriptores de archivo disponibles. </translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Reconstruir el índice de la cadena de bloques a partir de los archivos blk000??.dat actuales</translation> - </message> - <message> <source>Set maximum block size in bytes (default: %d)</source> <translation>Establecer tamaño máximo de bloque en bytes (por defecto: %d)</translation> </message> @@ -2367,6 +2247,10 @@ Dirección: %4 <translation>Establecer tamaño máximo de las transacciones de alta prioridad/comisión baja en bytes (por defecto: %d)</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Elegir directorio de datos al iniciar (predeterminado: 0)</translation> + </message> + <message> <source>Information</source> <translation>Información</translation> </message> @@ -2387,18 +2271,22 @@ Dirección: %4 <translation>Opciones del sservidor RPC:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Descartar aleatoriamente 1 de cada <n> mensajes de red</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Enviar información de trazas/depuración a la consola en lugar de al archivo debug.log</translation> </message> <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Mostrar todas las opciones de depuración (uso: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Mostrar pantalla de bienvenida en el inicio (predeterminado: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Reducir el archivo debug.log al iniciar el cliente (predeterminado: 1 sin -debug)</translation> </message> @@ -2407,6 +2295,10 @@ Dirección: %4 <translation>Transacción falló</translation> </message> <message> + <source>Start minimized</source> + <translation>Arrancar minimizado</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Monto de la transacción muy pequeño</translation> </message> @@ -2432,10 +2324,6 @@ Dirección: %4 <translation>Aviso</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Aviso: Esta versión es obsoleta, actualización necesaria!</translation> - </message> - <message> <source>on startup</source> <translation>al iniciar</translation> </message> diff --git a/src/qt/locale/bitcoin_es_MX.ts b/src/qt/locale/bitcoin_es_MX.ts index 4341bc821f..258308598e 100644 --- a/src/qt/locale/bitcoin_es_MX.ts +++ b/src/qt/locale/bitcoin_es_MX.ts @@ -1,4 +1,4 @@ -<TS language="es_MX" version="2.1"> +<TS language="es_MX" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -83,11 +83,11 @@ </message> <message> <source>Comma separated file (*.csv)</source> - <translation>Archivo separado por comas (*.CSV)</translation> + <translation>Arhchivo separado por comas (*.CSV)</translation> </message> <message> <source>Exporting Failed</source> - <translation>Fallo en la exportación</translation> + <translation>Exportación fallida</translation> </message> </context> <context> @@ -121,7 +121,7 @@ </message> <message> <source>Encrypt wallet</source> - <translation>Cartera encriptada.</translation> + <translation>Encriptar cartera.</translation> </message> <message> <source>This operation needs your wallet passphrase to unlock the wallet.</source> @@ -137,17 +137,13 @@ </message> <message> <source>Decrypt wallet</source> - <translation>Desencriptar la cartera</translation> + <translation>Desencriptar cartera</translation> </message> <message> <source>Change passphrase</source> <translation>Cambiar contraseña</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Ingrese la antugüa y nueva contraseña de la cartera</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Confirmar la encriptación de cartera</translation> </message> @@ -168,12 +164,8 @@ <translation>Cartera encriptada</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin se cerrará para finalizar el proceso de encriptación. Recuerda que encriptar tu cartera no protege completamente a tus bitcoins de ser robadas por malware infectando tu computadora.</translation> - </message> - <message> <source>Wallet encryption failed</source> - <translation>La encriptación de la cartera falló</translation> + <translation>Encriptación de la cartera fallida</translation> </message> <message> <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> @@ -185,11 +177,11 @@ </message> <message> <source>Wallet unlock failed</source> - <translation>El desbloqueo de la cartera Fallo</translation> + <translation>El desbloqueo de la cartera falló</translation> </message> <message> <source>The passphrase entered for the wallet decryption was incorrect.</source> - <translation>La contraseña ingresada para la des encriptación de la cartera es incorrecto</translation> + <translation>La contraseña ingresada para la desencriptación de la cartera es incorrecto</translation> </message> <message> <source>Wallet decryption failed</source> @@ -287,10 +279,6 @@ <translation>Enviar monedas a una dirección Bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Modificar las opciones de configuración de Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Respaldar cartera en otra ubicación</translation> </message> @@ -338,10 +326,6 @@ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> <translation>Mostrar mensaje de ayuda del nucleo de Bitcoin para optener una lista con los posibles comandos de Bitcoin</translation> </message> - <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n Activar conexión a la red de Bitcoin</numerusform><numerusform>%n Activar conexiones a la red de Bitcoin</numerusform></translation> - </message> <message> <source>Up to date</source> <translation>Actualizado al dia </translation> @@ -513,26 +497,6 @@ <source>command-line options</source> <translation>Opciones de comando de lineas</translation> </message> - <message> - <source>UI options</source> - <translation>Opciones de interfaz</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Definir idioma, por ejemplo "de_DE" (por defecto: Sistema local)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Iniciar minimizado</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostrar pantalla de arraque al iniciar (por defecto: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Escojer el directorio de información al iniciar (por defecto : 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -784,14 +748,6 @@ <translation>Mensaje:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Esta es una verificación de solicituda de pago.</translation> - </message> - <message> - <source>This is an unverified payment request.</source> - <translation>Esta es una solicitud de pago no verificada.</translation> - </message> - <message> <source>Pay To:</source> <translation>Pago para:</translation> </message> @@ -830,7 +786,7 @@ </message> <message> <source>The Bitcoin Core developers</source> - <translation>El nucleo de Bitcoin de desarrolladores</translation> + <translation>Los desarrolladores de Bitcoin Core</translation> </message> </context> <context> @@ -893,10 +849,6 @@ <translation>Tipo</translation> </message> <message> - <source>Address</source> - <translation>Domicilio</translation> - </message> - <message> <source>Open until %1</source> <translation>Abrir hasta %1</translation> </message> @@ -913,6 +865,10 @@ <translation>Generado pero no aprovado</translation> </message> <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + <message> <source>Received with</source> <translation>Recivido con</translation> </message> @@ -926,7 +882,7 @@ </message> <message> <source>Mined</source> - <translation>Minado</translation> + <translation>Minado </translation> </message> <message> <source>(n/a)</source> @@ -941,10 +897,6 @@ <translation>Escriba una transacción</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Direccion del destinatario de la transacción</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Cantidad removida del saldo o agregada </translation> </message> @@ -1025,7 +977,7 @@ </message> <message> <source>Exporting Failed</source> - <translation>Fallo en la exportación</translation> + <translation>Exportación fallida</translation> </message> <message> <source>There was an error trying to save the transaction history to %1.</source> @@ -1111,6 +1063,22 @@ <translation>Opciones de cartera:</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Escojer el directorio de información al iniciar (por defecto : 0)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Definir idioma, por ejemplo "de_DE" (por defecto: Sistema local)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Mostrar pantalla de arraque al iniciar (por defecto: 1)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Iniciar minimizado</translation> + </message> + <message> <source>Loading addresses...</source> <translation>Cargando direcciones...</translation> </message> diff --git a/src/qt/locale/bitcoin_es_UY.ts b/src/qt/locale/bitcoin_es_UY.ts index 13f33220a7..bb99466619 100644 --- a/src/qt/locale/bitcoin_es_UY.ts +++ b/src/qt/locale/bitcoin_es_UY.ts @@ -1,4 +1,4 @@ -<TS language="es_UY" version="2.1"> +<TS language="es_UY" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -72,10 +72,6 @@ <translation>Cambiar contraseña</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Ingrese la contraseña anterior y la nueva de acceso a el monedero</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Confirme el cifrado del monedero</translation> </message> @@ -158,10 +154,6 @@ <source>Tabs toolbar</source> <translation>Barra de herramientas</translation> </message> - <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n conexión activa a la red Bitcoin </numerusform><numerusform>%n conexiones activas a la red Bitcoin</numerusform></translation> - </message> <message> <source>Up to date</source> <translation>A la fecha</translation> @@ -429,13 +421,13 @@ <translation>Fecha</translation> </message> <message> - <source>Address</source> - <translation>Direccion </translation> - </message> - <message> <source>Open until %1</source> <translation>Abrir hasta %1</translation> </message> + <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> </context> <context> <name>TransactionView</name> diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index f1e5c2715c..c746107bc7 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -1,4 +1,4 @@ -<TS language="et" version="2.1"> +<TS language="et" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -6,6 +6,10 @@ <translation>Loo uus aadress</translation> </message> <message> + <source>&New</source> + <translation>&Uus</translation> + </message> + <message> <source>Copy the currently selected address to the system clipboard</source> <translation>Kopeeri märgistatud aadress vahemällu</translation> </message> @@ -14,8 +18,12 @@ <translation>&Kopeeri</translation> </message> <message> + <source>C&lose</source> + <translation>S&ulge</translation> + </message> + <message> <source>&Copy Address</source> - <translation>&Aadressi kopeerimine</translation> + <translation>&Kopeeri Aadress</translation> </message> <message> <source>Delete the currently selected address from the list</source> @@ -26,10 +34,18 @@ <translation>Ekspordi kuvatava vahelehe sisu faili</translation> </message> <message> + <source>&Export</source> + <translation>&Ekspordi</translation> + </message> + <message> <source>&Delete</source> <translation>&Kustuta</translation> </message> <message> + <source>C&hoose</source> + <translation>V&ali</translation> + </message> + <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> <translation>Need on sinu Bitcoini aadressid maksete saatmiseks. Müntide saatmisel kontrolli alati summat ning saaja aadressi.</translation> </message> @@ -45,6 +61,10 @@ <source>Comma separated file (*.csv)</source> <translation>Komaeraldatud fail (*.csv)</translation> </message> + <message> + <source>Exporting Failed</source> + <translation>Eksportimine Ebaõnnestus</translation> + </message> </context> <context> <name>AddressTableModel</name> @@ -104,10 +124,6 @@ <translation>Muuda salafraasi</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Sisesta rahakoti vana ning uus salafraas.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Kinnita rahakoti krüpteering</translation> </message> @@ -132,10 +148,6 @@ <translation>Rahakott krüpteeritud</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin sulgub krüpteeringu lõpetamiseks. Pea meeles, et rahakoti krüpteerimine ei välista bitcoinide vargust, kui sinu arvuti on nakatunud pahavaraga.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>Tõrge rahakoti krüpteerimisel</translation> </message> @@ -223,6 +235,10 @@ <translation>&Salafraasi muutmine</translation> </message> <message> + <source>Open &URI...</source> + <translation>Ava &URI...</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>Impordi blokid kettalt...</translation> </message> @@ -235,10 +251,6 @@ <translation>Saada münte Bitcoini aadressile</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Muuda Bitcoini seadeid</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Varunda rahakott teise asukohta</translation> </message> @@ -315,10 +327,6 @@ <translation>Bitcoini tuumik</translation> </message> <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n aktiivne ühendus Bitcoini võrku</numerusform><numerusform>%n aktiivset ühendust Bitcoini võrku</numerusform></translation> - </message> - <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n tund</numerusform><numerusform>%n tundi</numerusform></translation> </message> @@ -331,6 +339,14 @@ <translation><numerusform>%n nädal</numerusform><numerusform>%n nädalat</numerusform></translation> </message> <message> + <source>%1 and %2</source> + <translation>%1 ja %2</translation> + </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n aasta</numerusform><numerusform>%n aastat</numerusform></translation> + </message> + <message> <source>%1 behind</source> <translation>%1 maas</translation> </message> @@ -363,6 +379,36 @@ <translation>Jõuan...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Kuupäev: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Summa: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tüüp: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>&Märgis: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Aadress: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Saadetud tehing</translation> </message> @@ -371,17 +417,6 @@ <translation>Sisenev tehing</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Kuupäev: %1⏎ -Summa: %2⏎ -Tüüp: %3⏎ -Aadress: %4⏎</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Rahakott on <b>krüpteeritud</b> ning hetkel <b>avatud</b></translation> </message> @@ -400,10 +435,18 @@ Aadress: %4⏎</translation> <context> <name>CoinControlDialog</name> <message> + <source>Quantity:</source> + <translation>Kogus:</translation> + </message> + <message> <source>Amount:</source> <translation>Summa:</translation> </message> <message> + <source>Fee:</source> + <translation>Tasu:</translation> + </message> + <message> <source>Amount</source> <translation>Kogus</translation> </message> @@ -432,6 +475,50 @@ Aadress: %4⏎</translation> <translation>Kopeeri tehingu ID</translation> </message> <message> + <source>Copy fee</source> + <translation>Kopeeri tasu</translation> + </message> + <message> + <source>highest</source> + <translation>kõrgeim</translation> + </message> + <message> + <source>higher</source> + <translation>kõrgem</translation> + </message> + <message> + <source>high</source> + <translation>kõrge</translation> + </message> + <message> + <source>medium</source> + <translation>keskmine</translation> + </message> + <message> + <source>low</source> + <translation>madal</translation> + </message> + <message> + <source>lower</source> + <translation>madalam</translation> + </message> + <message> + <source>lowest</source> + <translation>madalaim</translation> + </message> + <message> + <source>(%1 locked)</source> + <translation>(%1 lukustatud)</translation> + </message> + <message> + <source>yes</source> + <translation>jah</translation> + </message> + <message> + <source>no</source> + <translation>ei</translation> + </message> + <message> <source>(no label)</source> <translation>(silti pole)</translation> </message> @@ -485,6 +572,10 @@ Aadress: %4⏎</translation> </context> <context> <name>FreespaceChecker</name> + <message> + <source>name</source> + <translation>nimi</translation> + </message> </context> <context> <name>HelpMessageDialog</name> @@ -512,26 +603,14 @@ Aadress: %4⏎</translation> <source>command-line options</source> <translation>käsurea valikud</translation> </message> - <message> - <source>UI options</source> - <translation>UI valikud</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Keele valik, nt "ee_ET" (vaikeväärtus: system locale)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Käivitu tegumiribale</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Käivitamisel teabeakna kuvamine (vaikeväärtus: 1)</translation> - </message> - </context> +</context> <context> <name>Intro</name> <message> + <source>Welcome</source> + <translation>Teretulemast</translation> + </message> + <message> <source>Bitcoin Core</source> <translation>Bitcoini tuumik</translation> </message> @@ -542,6 +621,14 @@ Aadress: %4⏎</translation> </context> <context> <name>OpenURIDialog</name> + <message> + <source>Open URI</source> + <translation>Ava URI</translation> + </message> + <message> + <source>URI:</source> + <translation>URI:</translation> + </message> </context> <context> <name>OptionsDialog</name> @@ -550,12 +637,8 @@ Aadress: %4⏎</translation> <translation>Valikud</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Käivita Bitcoin süsteemi logimisel.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Start Bitcoin sisselogimisel</translation> + <source>MB</source> + <translation>MB</translation> </message> <message> <source>Reset all client options to default.</source> @@ -570,6 +653,14 @@ Aadress: %4⏎</translation> <translation>&Võrk</translation> </message> <message> + <source>W&allet</source> + <translation>R&ahakott</translation> + </message> + <message> + <source>Expert</source> + <translation>Ekspert</translation> + </message> + <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> <translation>Bitcoini kliendi pordi automaatne avamine ruuteris. Toimib, kui sinu ruuter aktsepteerib UPnP ühendust.</translation> </message> @@ -602,10 +693,6 @@ Aadress: %4⏎</translation> <translation>&Minimeeri systray alale</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Sulgemise asemel minimeeri aken. Selle valiku tegemisel suletakse programm Menüüst "Välju" käsuga.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimeeri sulgemisel</translation> </message> @@ -618,10 +705,6 @@ Aadress: %4⏎</translation> <translation>Kasutajaliidese &keel:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Kasutajaliidese keele valimise koht. Valik rakendub Bitcoini käivitamisel.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>Summade kuvamise &Unit:</translation> </message> @@ -669,10 +752,10 @@ Aadress: %4⏎</translation> <translation>Mitte aegunud mine'itud jääk</translation> </message> <message> - <source>out of sync</source> - <translation>sünkimata</translation> + <source>Recent transactions</source> + <translation>Hiljutised tehingud</translation> </message> -</context> + </context> <context> <name>PaymentServer</name> <message> @@ -724,6 +807,10 @@ Aadress: %4⏎</translation> <translation>&Informatsioon</translation> </message> <message> + <source>General</source> + <translation>Üldine</translation> + </message> + <message> <source>Using OpenSSL version</source> <translation>Kasutan OpenSSL versiooni</translation> </message> @@ -736,6 +823,10 @@ Aadress: %4⏎</translation> <translation>Võrgustik</translation> </message> <message> + <source>Name</source> + <translation>Nimi</translation> + </message> + <message> <source>Number of connections</source> <translation>Ühenduste arv</translation> </message> @@ -748,6 +839,26 @@ Aadress: %4⏎</translation> <translation>Plokkide hetkearv</translation> </message> <message> + <source>Received</source> + <translation>Vastuvõetud</translation> + </message> + <message> + <source>Sent</source> + <translation>Saadetud</translation> + </message> + <message> + <source>Direction</source> + <translation>Suund</translation> + </message> + <message> + <source>Version</source> + <translation>Versioon</translation> + </message> + <message> + <source>Services</source> + <translation>Teenused</translation> + </message> + <message> <source>Last block time</source> <translation>Viimane ploki aeg</translation> </message> @@ -768,18 +879,10 @@ Aadress: %4⏎</translation> <translation>Debugimise logifail</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Ava Bitcoini logifail praegusest andmekaustast. Toiminguks võib kuluda kuni mõni sekund.</translation> - </message> - <message> <source>Clear console</source> <translation>Puhasta konsool</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Teretulemast Bitcoini RPC konsooli.</translation> - </message> - <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Ajaloo sirvimiseks kasuta üles ja alla nooli, ekraani puhastamiseks <b>Ctrl-L</b>.</translation> </message> @@ -787,18 +890,54 @@ Aadress: %4⏎</translation> <source>Type <b>help</b> for an overview of available commands.</source> <translation>Ülevaateks võimalikest käsklustest trüki <b>help</b>.</translation> </message> + <message> + <source>%1 B</source> + <translation>%1 B</translation> + </message> + <message> + <source>%1 KB</source> + <translation>%1 B</translation> + </message> + <message> + <source>%1 MB</source> + <translation>%1 MB</translation> + </message> + <message> + <source>%1 GB</source> + <translation>%1 GB</translation> + </message> </context> <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>&Summa:</translation> + </message> + <message> <source>&Label:</source> <translation>&Märgis</translation> </message> <message> + <source>&Message:</source> + <translation>&Sõnum:</translation> + </message> + <message> + <source>Show</source> + <translation>Näita</translation> + </message> + <message> + <source>Remove</source> + <translation>Eemalda</translation> + </message> + <message> <source>Copy label</source> <translation>Märgise kopeerimine</translation> </message> <message> + <source>Copy message</source> + <translation>Kopeeri sõnum</translation> + </message> + <message> <source>Copy amount</source> <translation>Kopeeri summa</translation> </message> @@ -852,7 +991,15 @@ Aadress: %4⏎</translation> <source>(no label)</source> <translation>(silti pole)</translation> </message> - </context> + <message> + <source>(no message)</source> + <translation>(sõnum puudub)</translation> + </message> + <message> + <source>(no amount)</source> + <translation>(summa puudub)</translation> + </message> +</context> <context> <name>SendCoinsDialog</name> <message> @@ -860,10 +1007,38 @@ Aadress: %4⏎</translation> <translation>Müntide saatmine</translation> </message> <message> + <source>Quantity:</source> + <translation>Kogus:</translation> + </message> + <message> <source>Amount:</source> <translation>Summa:</translation> </message> <message> + <source>Fee:</source> + <translation>Tasu:</translation> + </message> + <message> + <source>Choose...</source> + <translation>Vali...</translation> + </message> + <message> + <source>Hide</source> + <translation>Peida</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Soovitatud:</translation> + </message> + <message> + <source>normal</source> + <translation>normaalne</translation> + </message> + <message> + <source>fast</source> + <translation>kiire</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Saatmine mitmele korraga</translation> </message> @@ -896,8 +1071,12 @@ Aadress: %4⏎</translation> <translation>Kopeeri summa</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Saaja aadress ei ole kehtiv, palun kontrolli.</translation> + <source>Copy fee</source> + <translation>Kopeeri tasu</translation> + </message> + <message> + <source>or</source> + <translation>või</translation> </message> <message> <source>The amount to pay must be larger than 0.</source> @@ -912,10 +1091,6 @@ Aadress: %4⏎</translation> <translation>Summa koos tehingu tasuga %1 ületab sinu jääki.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Ühe saatmisega topelt-adressaati olla ei tohi.</translation> - </message> - <message> <source>(no label)</source> <translation>(silti pole)</translation> </message> @@ -969,10 +1144,6 @@ Aadress: %4⏎</translation> <translation>&Allkirjastamise teade</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Omandiõigsuse tõestamiseks saad sõnumeid allkirjastada oma aadressiga. Ettevaatust petturitega, kes üritavad saada sinu allkirja endale saada. Allkirjasta ainult korralikult täidetud avaldusi, millega nõustud.</translation> - </message> - <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1017,10 +1188,6 @@ Aadress: %4⏎</translation> <translation>&Kinnita Sõnum</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Kinnitamiseks sisesta allkirjastamise aadress, sõnum (kindlasti kopeeri täpselt ka reavahetused, tühikud, tabulaatorid jms) ning allolev signatuur.</translation> - </message> - <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>Kinnita sõnum tõestamaks selle allkirjastatust määratud Bitcoini aadressiga.</translation> </message> @@ -1102,7 +1269,11 @@ Aadress: %4⏎</translation> </context> <context> <name>TrafficGraphWidget</name> - </context> + <message> + <source>KB/s</source> + <translation>KB/s</translation> + </message> +</context> <context> <name>TransactionDesc</name> <message> @@ -1121,10 +1292,6 @@ Aadress: %4⏎</translation> <source>Status</source> <translation>Staatus</translation> </message> - <message numerus="yes"> - <source>, broadcast through %n node(s)</source> - <translation><numerusform>, levita läbi %n node'i</numerusform><numerusform>, levita läbi %n node'i</numerusform></translation> - </message> <message> <source>Date</source> <translation>Kuupäev</translation> @@ -1157,10 +1324,6 @@ Aadress: %4⏎</translation> <source>Credit</source> <translation>Krediit</translation> </message> - <message numerus="yes"> - <source>matures in %n more block(s)</source> - <translation><numerusform>aegub %n bloki pärast</numerusform><numerusform>aegub %n bloki pärast</numerusform></translation> - </message> <message> <source>not accepted</source> <translation>mitte aktsepteeritud</translation> @@ -1217,10 +1380,6 @@ Aadress: %4⏎</translation> <source>, has not been successfully broadcast yet</source> <translation>, veel esitlemata</translation> </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>Avaneb %n bloki pärast</numerusform><numerusform>Avaneb %n bloki pärast</numerusform></translation> - </message> <message> <source>unknown</source> <translation>tundmatu</translation> @@ -1248,14 +1407,6 @@ Aadress: %4⏎</translation> <translation>Tüüp</translation> </message> <message> - <source>Address</source> - <translation>Aadress</translation> - </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>Avaneb %n bloki pärast</numerusform><numerusform>Avaneb %n bloki pärast</numerusform></translation> - </message> - <message> <source>Open until %1</source> <translation>Avatud kuni %1</translation> </message> @@ -1272,6 +1423,10 @@ Aadress: %4⏎</translation> <translation>Loodud, kuid aktsepteerimata</translation> </message> <message> + <source>Label</source> + <translation>Silt</translation> + </message> + <message> <source>Received with</source> <translation>Saadud koos</translation> </message> @@ -1308,10 +1463,6 @@ Aadress: %4⏎</translation> <translation>Tehingu tüüp.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Tehingu saaja aadress.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Jäägile lisatud või eemaldatud summa.</translation> </message> @@ -1399,6 +1550,10 @@ Aadress: %4⏎</translation> <translation>Kuva tehingu detailid</translation> </message> <message> + <source>Exporting Failed</source> + <translation>Eksportimine Ebaõnnestus</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Komaeraldatud fail (*.csv)</translation> </message> @@ -1451,6 +1606,10 @@ Aadress: %4⏎</translation> <context> <name>WalletView</name> <message> + <source>&Export</source> + <translation>&Ekspordi</translation> + </message> + <message> <source>Export the data in the current tab to a file</source> <translation>Ekspordi kuvatava vahelehe sisu faili</translation> </message> @@ -1546,10 +1705,6 @@ Aadress: %4⏎</translation> <translation>Tuvastati vigane bloki andmebaas</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Leia oma IP aadress (vaikeväärtus: 1, kui kuulatakse ning puudub -externalip)</translation> - </message> - <message> <source>Do you want to rebuild the block database now?</source> <translation>Kas soovid bloki andmebaasi taastada?</translation> </message> @@ -1578,10 +1733,6 @@ Aadress: %4⏎</translation> <translation>Pordi kuulamine nurjus. Soovikorral kasuta -listen=0.</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Taasta bloki jada indeks blk000??.dat failist</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>Kontrollin blokke...</translation> </message> @@ -1590,6 +1741,10 @@ Aadress: %4⏎</translation> <translation>Kontrollin rahakotti...</translation> </message> <message> + <source>Wallet options:</source> + <translation>Rahakoti valikud:</translation> + </message> + <message> <source>Imports blocks from external blk000??.dat file</source> <translation>Impordi blokid välisest blk000??.dat failist</translation> </message> @@ -1598,14 +1753,50 @@ Aadress: %4⏎</translation> <translation>Informatsioon</translation> </message> <message> + <source>RPC server options:</source> + <translation>RPC serveri valikud:</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Saada jälitus/debug, debug.log faili asemel, konsooli</translation> </message> <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Keele valik, nt "ee_ET" (vaikeväärtus: system locale)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Käivitamisel teabeakna kuvamine (vaikeväärtus: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Kahanda programmi käivitamisel debug.log faili (vaikeväärtus: 1, kui ei ole -debug)</translation> </message> <message> + <source>Signing transaction failed</source> + <translation>Tehingu allkirjastamine ebaõnnestus</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Käivitu tegumiribale</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Tehingu summa on tasu maksmiseks liiga väikene</translation> + </message> + <message> + <source>Transaction amount too small</source> + <translation>Tehingu summa liiga väikene</translation> + </message> + <message> + <source>Transaction too large</source> + <translation>Tehing liiga suur</translation> + </message> + <message> + <source>UI Options:</source> + <translation>UI Valikud:</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Kasuta kuulatava pordi määramiseks UPnP ühendust (vaikeväärtus: 1, kui kuulatakse)</translation> </message> @@ -1618,8 +1809,8 @@ Aadress: %4⏎</translation> <translation>Hoiatus</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Hoiatus: versioon on aegunud, uuendus on nõutav!</translation> + <source>on startup</source> + <translation>käivitamisel</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -1662,6 +1853,10 @@ Aadress: %4⏎</translation> <translation>Viga wallet.dat käivitamisel. Vigane rahakkott</translation> </message> <message> + <source>(default: %s)</source> + <translation>(vaikimisi: %s)</translation> + </message> + <message> <source>Error loading wallet.dat</source> <translation>Viga wallet.dat käivitamisel</translation> </message> diff --git a/src/qt/locale/bitcoin_eu_ES.ts b/src/qt/locale/bitcoin_eu_ES.ts index 34c34c4431..3de9ad5a2f 100644 --- a/src/qt/locale/bitcoin_eu_ES.ts +++ b/src/qt/locale/bitcoin_eu_ES.ts @@ -1,4 +1,4 @@ -<TS language="eu_ES" version="2.1"> +<TS language="eu_ES" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -72,10 +72,6 @@ <translation>Aldatu pasahitza</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Sartu zorroaren pasahitz zaharra eta berria.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Berretsi zorroaren enkriptazioa</translation> </message> @@ -509,10 +505,6 @@ <translation>Mota</translation> </message> <message> - <source>Address</source> - <translation>Helbidea</translation> - </message> - <message> <source>Open until %1</source> <translation>Zabalik %1 arte</translation> </message> @@ -529,6 +521,10 @@ <translation>Sortua, baina ez onartua</translation> </message> <message> + <source>Label</source> + <translation>Etiketa</translation> + </message> + <message> <source>Received with</source> <translation>Jasota honekin: </translation> </message> @@ -561,10 +557,6 @@ <translation>Transakzio mota.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Transakzioaren xede-helbidea.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Saldoan kendu edo gehitutako kopurua.</translation> </message> diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index 2f9a1c7345..5eeea04684 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -1,7 +1,11 @@ -<TS language="fa" version="2.1"> +<TS language="fa" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>برای تغییر آدرس و یا برچسب کلیک راست کنید.</translation> + </message> + <message> <source>Create a new address</source> <translation>ایجاد نشانی جدید</translation> </message> @@ -42,10 +46,30 @@ <translation>&حذف</translation> </message> <message> + <source>Choose the address to send coins to</source> + <translation>آدرس مورد نظر برای ارسال کوین ها را انتخاب کنید</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>آدرس موردنظر برای دریافت کوین ها را انتخاب کنید.</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>آدرس های ارسال کننده</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>آدرس های دریافت کننده</translation> + </message> + <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> <translation>اینها نشانیهای بیتکوین شما برای ارسال وجود هستند. همیشه قبل از ارسال سکهها، نشانی دریافتکننده و مقدار ارسالی را بررسی کنید.</translation> </message> <message> + <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> + <translation>اینها نشانیهای بیتکوین شما برای دریافت وجوه هستند. توصیه میشود یک نشانی دریافت جدید برای هر تبادل استفاده کنید.</translation> + </message> + <message> <source>Copy &Label</source> <translation>کپی و برچسب&گذاری</translation> </message> @@ -65,7 +89,11 @@ <source>Exporting Failed</source> <translation>استخراج انجام نشد</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>خطایی هنگام تلاش برای ذخیرهٔ لیست آدرس ها در %1 رخ داد.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -124,10 +152,6 @@ <translation>تغییر گذرواژه</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>گذرواژهٔ قدیمی و جدید کیف پول را وارد کنید.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>تأیید رمزنگاری کیف پول</translation> </message> @@ -140,6 +164,10 @@ <translation>آیا مطمئن هستید که میخواهید کیف پول خود را رمزنگاری کنید؟</translation> </message> <message> + <source>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.</source> + <translation>هسته بیتکوین هم اکنون بسته میشود تا فرایند رمزگذاری را تمام کند. به خاطر داشته باشید که رمزگذاری کردن کیف پولتان نمیتواند به طور کامل بیتکوینهای شما را در برابر دزدیده شدن توسط بدافزارهایی که رایانهی شما را آلوده میکنند، محافظت نماید.</translation> + </message> + <message> <source>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.</source> <translation>مهم: هر نسخهٔ پشتیبانی که تا کنون از کیف پول خود تهیه کردهاید، باید با کیف پول رمزنگاری شدهٔ جدید جایگزین شود. به دلایل امنیتی، پروندهٔ قدیمی کیف پول بدون رمزنگاری، تا زمانی که از کیف پول رمزنگاریشدهٔ جدید استفاده نکنید، غیرقابل استفاده خواهد بود.</translation> </message> @@ -152,8 +180,12 @@ <translation>کیف پول رمزنگاری شد</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>بیتکوین هم اکنون بسته میشود تا فرایند رمزگذاری را تمام کند. به خاطر داشته باشید که رمزگذاری کردن کیف پولتان نمیتواند به طور کامل بیتکوینهای شما را در برابر دزدیده شدن توسط بدافزارهایی که احتمالاً رایانهٔ شما را آلوده میکنند، محافظت نماید.</translation> + <source>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>.</source> + <translation>رمز جدید کیف پول خود را وارد کنید.<br/>از رمز عبوری استفاده کنید که<b> حداقل 10 کاراکتر تصادفی </b> و یا <b> حداقل 8 حرف داشته باشد.</b></translation> + </message> + <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>رمز عبور قدیمی و رمز عبور جدید کیف پول خود را وارد گنید.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -199,6 +231,10 @@ <translation>&بررسی اجمالی</translation> </message> <message> + <source>Node</source> + <translation>گره</translation> + </message> + <message> <source>Show general overview of wallet</source> <translation>نمایش بررسی اجمالی کیف پول</translation> </message> @@ -243,6 +279,18 @@ <translation>&تغییر گذرواژه...</translation> </message> <message> + <source>&Sending addresses...</source> + <translation>&در حال ارسال آدرس ها...</translation> + </message> + <message> + <source>&Receiving addresses...</source> + <translation>&در حال دریافت آدرس ها...</translation> + </message> + <message> + <source>Open &URI...</source> + <translation>باز کردن &آدرس</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>دریافت بلوکها از دیسک...</translation> </message> @@ -255,10 +303,6 @@ <translation>ارسال وجه به نشانی بیتکوین</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>تغییر و اصلاح تنظیمات پیکربندی بیتکوین</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>تهیهٔ پشتیبان از کیف پول در یک مکان دیگر</translation> </message> @@ -295,6 +339,10 @@ <translation>&دریافت</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>نمایش اطلاعات در مورد بیتکوین</translation> + </message> + <message> <source>&Show / Hide</source> <translation>&نمایش/ عدم نمایش</translation> </message> @@ -334,6 +382,18 @@ <source>Bitcoin Core</source> <translation> هسته Bitcoin </translation> </message> + <message> + <source>&About Bitcoin Core</source> + <translation>درباره هسته ی بیت کوین</translation> + </message> + <message> + <source>Show the list of used sending addresses and labels</source> + <translation>نمایش لیست آدرس های ارسال و لیبل ها</translation> + </message> + <message> + <source>Show the list of used receiving addresses and labels</source> + <translation>نمایش لیست آدرس های دریافت و لیبل ها</translation> + </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n ارتباط فعال با شبکهٔ بیتکوین</numerusform></translation> @@ -395,18 +455,6 @@ <translation>تراکنش دریافت شد</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>تاریخ: %1 -مبلغ: %2 -نوع: %3 -نشانی: %4 -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>کیف پول <b>رمزنگاری شده</b> است و هماکنون <b>باز</b> است</translation> </message> @@ -425,22 +473,74 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>انتخاب سکه</translation> + </message> + <message> + <source>Quantity:</source> + <translation>تعداد:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>بایت ها:</translation> + </message> + <message> <source>Amount:</source> <translation>مبلغ:</translation> </message> <message> + <source>Priority:</source> + <translation>اولویت:</translation> + </message> + <message> + <source>Fee:</source> + <translation>هزینه:</translation> + </message> + <message> + <source>After Fee:</source> + <translation>هزینه ی پسین:</translation> + </message> + <message> + <source>Change:</source> + <translation>پول خورد:</translation> + </message> + <message> + <source>Tree mode</source> + <translation>مدل درختی</translation> + </message> + <message> + <source>List mode</source> + <translation>مدل لیست</translation> + </message> + <message> <source>Amount</source> <translation>مبلغ</translation> </message> <message> + <source>Received with label</source> + <translation>دریافت شده با برچسب</translation> + </message> + <message> + <source>Received with address</source> + <translation>دریافت شده با نشانی</translation> + </message> + <message> <source>Date</source> <translation>تاریخ</translation> </message> <message> + <source>Confirmations</source> + <translation>تاییدیه ها</translation> + </message> + <message> <source>Confirmed</source> <translation>تأیید شده</translation> </message> <message> + <source>Priority</source> + <translation>اولویت</translation> + </message> + <message> <source>Copy address</source> <translation>کپی نشانی</translation> </message> @@ -457,6 +557,46 @@ Address: %4 <translation>کپی شناسهٔ تراکنش</translation> </message> <message> + <source>highest</source> + <translation>بیشترین</translation> + </message> + <message> + <source>higher</source> + <translation>بیشتر</translation> + </message> + <message> + <source>high</source> + <translation>زیاد</translation> + </message> + <message> + <source>medium-high</source> + <translation>متوسط متمایل به زیاد</translation> + </message> + <message> + <source>medium</source> + <translation>متوسط</translation> + </message> + <message> + <source>low-medium</source> + <translation>متوسط متمایل به کم</translation> + </message> + <message> + <source>low</source> + <translation>کم</translation> + </message> + <message> + <source>lower</source> + <translation>کمتر</translation> + </message> + <message> + <source>lowest</source> + <translation>کمترین</translation> + </message> + <message> + <source>none</source> + <translation>هیچکدام</translation> + </message> + <message> <source>yes</source> <translation>بله</translation> </message> @@ -468,7 +608,11 @@ Address: %4 <source>(no label)</source> <translation>(بدون برچسب)</translation> </message> - </context> + <message> + <source>(change)</source> + <translation>(تغییر)</translation> + </message> +</context> <context> <name>EditAddressDialog</name> <message> @@ -550,6 +694,10 @@ Address: %4 <translation>نسخه</translation> </message> <message> + <source>About Bitcoin Core</source> + <translation>درباره هسته ی بیت کوین</translation> + </message> + <message> <source>Command-line options</source> <translation>گزینههای خطفرمان</translation> </message> @@ -561,26 +709,6 @@ Address: %4 <source>command-line options</source> <translation>گزینههای خط فرمان</translation> </message> - <message> - <source>UI options</source> - <translation>گزینههای رابط کاربری</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>زبان را تنظیم کنید؛ برای مثال «de_DE» (زبان پیشفرض محلی)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>اجرای برنامه به صورت کوچکشده</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>نمایش پنجرهٔ خوشامدگویی در ابتدای اجرای برنامه (پیشفرض: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>انتخاب مسیر دادهها در ابتدای اجرای برنامه (پیشفرض: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -589,6 +717,14 @@ Address: %4 <translation>خوشآمدید</translation> </message> <message> + <source>Welcome to Bitcoin Core.</source> + <translation>به هسته بیت کوین خوش آمدید.</translation> + </message> + <message> + <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source> + <translation>از آنجایی که این اولین اجرای برنامه است، شما میتوانید مسیر ذخیرهٔ دادهها را انتخاب کنید.</translation> + </message> + <message> <source>Use the default data directory</source> <translation>استفاده از مسیر پیشفرض</translation> </message> @@ -619,14 +755,6 @@ Address: %4 <translation>&عمومی</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>اجرای خودکار بیتکوین در زمان ورود به سیستم.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&اجرای بیتکوین با ورود به سیستم</translation> - </message> - <message> <source>Reset all client options to default.</source> <translation>بازنشانی تمام تنظیمات به پیشفرض.</translation> </message> @@ -675,10 +803,6 @@ Address: %4 <translation>&کوچک کردن به سینی بهجای نوار وظیفه</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>مخفی کردن در نوار کناری بهجای خروج هنگام بستن پنجره. زمانی که این گزینه فعال است، برنامه فقط با استفاده از گزینهٔ خروج در منو قابل بسته شدن است.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>کوچک کردن &در زمان بسته شدن</translation> </message> @@ -691,10 +815,6 @@ Address: %4 <translation>زبان &رابط کاربری:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>زبان رابط کاربر میتواند در اینجا تنظیم شود. تنظیمات بعد از ظروع مجدد بیتکوین اعمال خواهد شد.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&واحد نمایش مبالغ:</translation> </message> @@ -715,6 +835,10 @@ Address: %4 <translation>پیشفرض</translation> </message> <message> + <source>none</source> + <translation>هیچکدام</translation> + </message> + <message> <source>Confirm options reset</source> <translation>تأییدِ بازنشانی گزینهها</translation> </message> @@ -758,6 +882,10 @@ Address: %4 <translation>تراز استخراج شده از معدن که هنوز بالغ نشده است</translation> </message> <message> + <source>Balances</source> + <translation>تراز ها</translation> + </message> + <message> <source>Total:</source> <translation>جمع کل:</translation> </message> @@ -766,10 +894,14 @@ Address: %4 <translation>تراز کل فعلی شما</translation> </message> <message> - <source>out of sync</source> - <translation>ناهمگام</translation> + <source>Spendable:</source> + <translation>:قابل خرج کردن</translation> </message> -</context> + <message> + <source>Recent transactions</source> + <translation>تراکنش های اخیر</translation> + </message> + </context> <context> <name>PaymentServer</name> <message> @@ -777,9 +909,25 @@ Address: %4 <translation>مدیریت URI</translation> </message> <message> + <source>Payment request rejected</source> + <translation>درخواست پرداخت رد شد.</translation> + </message> + <message> + <source>Payment request error</source> + <translation>خطای درخواست پرداخت</translation> + </message> + <message> <source>Cannot start bitcoin: click-to-pay handler</source> <translation>نمیتوان بیتکوین را اجرا کرد: کنترلکنندهٔ کلیک-و-پرداخت</translation> </message> + <message> + <source>Payment request expired.</source> + <translation>درخواست پرداخت منقضی شد.</translation> + </message> + <message> + <source>Invalid payment request.</source> + <translation>درخواست پرداخت نامعتبر</translation> + </message> </context> <context> <name>PeerTableModel</name> @@ -791,6 +939,10 @@ Address: %4 <translation>مبلغ</translation> </message> <message> + <source>None</source> + <translation>هیچکدام</translation> + </message> + <message> <source>N/A</source> <translation>ناموجود</translation> </message> @@ -849,6 +1001,22 @@ Address: %4 <translation>تعداد فعلی بلوکها</translation> </message> <message> + <source>Received</source> + <translation>دریافتی</translation> + </message> + <message> + <source>Sent</source> + <translation>ارسال شده</translation> + </message> + <message> + <source>Version</source> + <translation>نسخه</translation> + </message> + <message> + <source>Services</source> + <translation>سرویس ها</translation> + </message> + <message> <source>Last block time</source> <translation>زمان آخرین بلوک</translation> </message> @@ -873,16 +1041,12 @@ Address: %4 <translation>فایلِ لاگِ اشکال زدایی</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>فایلِ لاگِ اشکال زدایی Bitcoin را از دایرکتوری جاری داده ها باز کنید. این عملیات ممکن است برای فایلهای لاگِ حجیم طولانی شود.</translation> - </message> - <message> <source>Clear console</source> <translation>پاکسازی کنسول</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>به کنسور RPC بیتکوین خوش آمدید.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>به کنسول RPC هسته بیت کوین خوش آمدید.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -904,6 +1068,14 @@ Address: %4 <translation>&برچسب:</translation> </message> <message> + <source>Show</source> + <translation>نمایش</translation> + </message> + <message> + <source>Remove</source> + <translation>حذف کردن</translation> + </message> + <message> <source>Copy label</source> <translation>کپی برچسب</translation> </message> @@ -973,10 +1145,38 @@ Address: %4 <translation>ارسال سکه</translation> </message> <message> + <source>Quantity:</source> + <translation>تعداد:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>بایت ها:</translation> + </message> + <message> <source>Amount:</source> <translation>مبلغ:</translation> </message> <message> + <source>Priority:</source> + <translation>اولویت:</translation> + </message> + <message> + <source>Fee:</source> + <translation>هزینه:</translation> + </message> + <message> + <source>After Fee:</source> + <translation>هزینه ی پسین:</translation> + </message> + <message> + <source>Change:</source> + <translation>پول خورد:</translation> + </message> + <message> + <source>fast</source> + <translation>سریع</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>ارسال به چند دریافتکنندهٔ بهطور همزمان</translation> </message> @@ -1013,10 +1213,6 @@ Address: %4 <translation>یا</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>نشانی گیرنده معتبر نیست؛ لطفا دوباره بررسی کنید.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>مبلغ پرداخت باید بیشتر از ۰ باشد.</translation> </message> @@ -1029,13 +1225,17 @@ Address: %4 <translation>با احتساب هزینهٔ %1 برای هر تراکنش، مجموع میزان پرداختی از مبلغ تراز شما بیشتر میشود.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>یک نشانی تکراری پیدا شد. در هر عملیات ارسال، به هر نشانی فقط مبلغ میتوان ارسال کرد.</translation> + <source>Payment request expired.</source> + <translation>درخواست پرداخت منقضی شد.</translation> </message> <message> <source>(no label)</source> <translation>(بدون برچسب)</translation> </message> + <message> + <source>Are you sure you want to send?</source> + <translation>آیا مطمئن هستید که می خواهید ارسال کنید؟</translation> + </message> </context> <context> <name>SendCoinsEntry</name> @@ -1056,6 +1256,18 @@ Address: %4 <translation>&برچسب:</translation> </message> <message> + <source>Choose previously used address</source> + <translation>انتخاب نشانی پیشتر استفاده شده</translation> + </message> + <message> + <source>This is a normal payment.</source> + <translation>این یک پرداخت عادی است</translation> + </message> + <message> + <source>The Bitcoin address to send the payment to</source> + <translation>نشانی بیتکوین برای ارسال پرداخت به آن</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1068,6 +1280,10 @@ Address: %4 <translation>Alt+P</translation> </message> <message> + <source>Remove this entry</source> + <translation>حذف این مدخل</translation> + </message> + <message> <source>Message:</source> <translation>پیام:</translation> </message> @@ -1086,8 +1302,12 @@ Address: %4 <translation>ا&مضای پیام</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>برای احراز اینکه پیامها از جانب شما هستند، میتوانید آنها را با نشانی خودتان امضا کنید. مراقب باشید چیزی که بدان اطمینان ندارید را امضا نکنید زیرا حملات فیشینگ ممکن است بخواهند از.پیامی با امضای شما سوءاستفاده کنند. تنها مواردی را که حاوی اطلاعات دقیق و قابل قبول برای شما هستند امضا کنید.</translation> + <source>The Bitcoin address to sign the message with</source> + <translation>نشانی بیتکوین برای امضاء پیغام با آن</translation> + </message> + <message> + <source>Choose previously used address</source> + <translation>انتخاب نشانی پیشتر استفاده شده</translation> </message> <message> <source>Alt+A</source> @@ -1134,8 +1354,8 @@ Address: %4 <translation>&شناسایی پیام</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>برای شناسایی پیام، نشانیِ امضا کننده و متن پیام را وارد کنید. (مطمئن شوید که فاصلهها، تبها و خطوط را عیناً کپی میکنید.) مراقب باشید در امضا چیزی بیشتر از آنچه در پیام میبینید وجود نداشته باشد تا فریب دزدان اینترنتی و حملات از نوع MITM را نخورید.</translation> + <source>The Bitcoin address the message was signed with</source> + <translation>نشانی بیتکوین که پیغام با آن امضاء شده</translation> </message> <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> @@ -1209,13 +1429,21 @@ Address: %4 <translation> هسته Bitcoin </translation> </message> <message> + <source>The Bitcoin Core developers</source> + <translation>توسعهدهندگان هسته بیتکوین</translation> + </message> + <message> <source>[testnet]</source> <translation>آزمایش شبکه</translation> </message> </context> <context> <name>TrafficGraphWidget</name> - </context> + <message> + <source>KB/s</source> + <translation>کیلوبایت</translation> + </message> +</context> <context> <name>TransactionDesc</name> <message> @@ -1364,10 +1592,6 @@ Address: %4 <source>Type</source> <translation>نوع</translation> </message> - <message> - <source>Address</source> - <translation>نشانی</translation> - </message> <message numerus="yes"> <source>Open for %n more block(s)</source> <translation><numerusform>باز برای %n بلوک دیگر</numerusform></translation> @@ -1389,6 +1613,10 @@ Address: %4 <translation>تولید شده ولی قبول نشده</translation> </message> <message> + <source>Label</source> + <translation>برچسب</translation> + </message> + <message> <source>Received with</source> <translation>دریافتشده با</translation> </message> @@ -1425,10 +1653,6 @@ Address: %4 <translation>نوع تراکنش.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>نشانی مقصد تراکنش.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>مبلغ کسر شده و یا اضافه شده به تراز.</translation> </message> @@ -1520,6 +1744,10 @@ Address: %4 <translation>استخراج انجام نشد</translation> </message> <message> + <source>Exporting Successful</source> + <translation>استخراج موفق</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>پروندهٔ نوع CSV جداشونده با کاما (*.csv)</translation> </message> @@ -1659,10 +1887,6 @@ Address: %4 <translation>یک پایگاه داده ی بلوک خراب یافت شد</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>آدرس آی.پی. خود را شناسایی کنید (پیش فرض:1 در زمان when listening وno -externalip)</translation> - </message> - <message> <source>Do you want to rebuild the block database now?</source> <translation>آیا مایلید که اکنون پایگاه داده ی بلوک را بازسازی کنید؟</translation> </message> @@ -1679,10 +1903,22 @@ Address: %4 <translation>خطا در بازگشایی پایگاه داده ی بلوک</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>خطا: یک خطای داخلی مهلک روی داد، debug.log را برای جزئیات ببینید</translation> + </message> + <message> + <source>Error: Disk space is low!</source> + <translation>خطا: فضای دیسک کم است!</translation> + </message> + <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>شنیدن هر گونه درگاه انجام پذیر نیست. ازlisten=0 برای اینکار استفاده کیند.</translation> </message> <message> + <source>Importing...</source> + <translation>در حال پیادهسازی...</translation> + </message> + <message> <source>Verifying blocks...</source> <translation>در حال بازبینی بلوک ها...</translation> </message> @@ -1691,6 +1927,14 @@ Address: %4 <translation>در حال بازبینی کیف پول...</translation> </message> <message> + <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>هشدار: تاریخ و ساعت کامپیوتر خود را بررسی کنید. اگر ساعت درست نباشد هسته بیتکوین به درستی کار نخواهد کرد.</translation> + </message> + <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>انتخاب مسیر دادهها در ابتدای اجرای برنامه (پیشفرض: 0)</translation> + </message> + <message> <source>Information</source> <translation>اطلاعات</translation> </message> @@ -1699,10 +1943,26 @@ Address: %4 <translation>اطلاعات ردگیری/اشکالزدایی را به جای فایل لاگ اشکالزدایی به کنسول بفرستید</translation> </message> <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>زبان را تنظیم کنید؛ برای مثال «de_DE» (زبان پیشفرض محلی)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>نمایش پنجرهٔ خوشامدگویی در ابتدای اجرای برنامه (پیشفرض: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>فایل debug.log را در startup مشتری کوچک کن (پیش فرض:1 اگر اشکال زدایی روی نداد)</translation> </message> <message> + <source>Start minimized</source> + <translation>اجرای برنامه به صورت کوچکشده</translation> + </message> + <message> + <source>UI Options:</source> + <translation>گزینههای رابط کاربری:</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>از UPnP برای شناسایی درگاه شنیداری استفاده کنید (پیش فرض:1 در زمان شنیدن)</translation> </message> @@ -1715,10 +1975,6 @@ Address: %4 <translation>هشدار</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>هشدار: این نسخه قدیمی است، روزآمدسازی مورد نیاز است</translation> - </message> - <message> <source>Password for JSON-RPC connections</source> <translation>JSON-RPC عبارت عبور برای ارتباطات</translation> </message> diff --git a/src/qt/locale/bitcoin_fa_IR.ts b/src/qt/locale/bitcoin_fa_IR.ts index 0a3071a6c7..1174e24b46 100644 --- a/src/qt/locale/bitcoin_fa_IR.ts +++ b/src/qt/locale/bitcoin_fa_IR.ts @@ -1,4 +1,4 @@ -<TS language="fa_IR" version="2.1"> +<TS language="fa_IR" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -14,30 +14,78 @@ <translation>کپی کردن حساب انتخاب شده به حافظه سیستم - کلیپ بورد</translation> </message> <message> + <source>&Copy</source> + <translation>کپی</translation> + </message> + <message> + <source>C&lose</source> + <translation>بستن</translation> + </message> + <message> <source>&Copy Address</source> - <translation>و کپی آدرس</translation> + <translation>کپی آدرس</translation> + </message> + <message> + <source>Delete the currently selected address from the list</source> + <translation>حذف آدرس های انتخاب شده از لیست</translation> </message> <message> <source>Export the data in the current tab to a file</source> <translation>صدور داده نوار جاری به یک فایل</translation> </message> <message> + <source>&Export</source> + <translation>صدور</translation> + </message> + <message> <source>&Delete</source> - <translation>و حذف</translation> + <translation>حذف</translation> + </message> + <message> + <source>Choose the address to send coins to</source> + <translation>انتخاب آدرس جهت ارسال کوین ها به آن آدرس</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>انتخاب آدرس جهت دریافت کوین ها از آن آدرس</translation> + </message> + <message> + <source>C&hoose</source> + <translation>انتخاب</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>ارسال آدرس ها</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>دریافت آدرس ها</translation> </message> <message> <source>Copy &Label</source> - <translation>کپی و برچسب</translation> + <translation>کپی برچسب</translation> </message> <message> <source>&Edit</source> - <translation>و ویرایش</translation> + <translation>ویرایش</translation> + </message> + <message> + <source>Export Address List</source> + <translation>صدور لیست آدرس</translation> </message> <message> <source>Comma separated file (*.csv)</source> - <translation>Comma separated file (*.csv) فایل جداگانه دستوری</translation> + <translation>فایل سی اس وی (*.csv)</translation> </message> - </context> + <message> + <source>Exporting Failed</source> + <translation>صدور با شکست مواجه شد</translation> + </message> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>خطایی به هنگام ذخیره لیست آدرس در %1 رخ داده است. لطفا دوباره تلاش کنید.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -56,6 +104,10 @@ <context> <name>AskPassphraseDialog</name> <message> + <source>Passphrase Dialog</source> + <translation>دیالوگ رمزعبور</translation> + </message> + <message> <source>Enter passphrase</source> <translation>رمز/پَس فرِیز را وارد کنید</translation> </message> @@ -92,20 +144,20 @@ <translation>تغییر رمز/پَس فرِیز</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>رمز/پَس فرِیزِ قدیم و جدید را در wallet وارد کنید</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>رمزگذاری wallet را تایید کنید</translation> </message> <message> + <source>Warning: The Caps Lock key is on!</source> + <translation>اخطار: کلید Caps Lock فعال است!</translation> + </message> + <message> <source>Wallet encrypted</source> <translation>تایید رمزگذاری</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin برای اتمام فرایند رمزگذاری بسته خواهد شد. به خاطر داشته باشید که رمزگذاری WALLET شما، کامپیوتر شما را از آلودگی به بدافزارها مصون نمی دارد.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>رمز قدیمی و جدید کیف پول را وارد کنید.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -131,7 +183,11 @@ <source>Wallet decryption failed</source> <translation>کشف رمز wallet انجام نشد</translation> </message> - </context> + <message> + <source>Wallet passphrase was successfully changed.</source> + <translation>رمز عبور کیف پول با موفقیت تغییر کرد.</translation> + </message> +</context> <context> <name>BitcoinGUI</name> <message> @@ -168,11 +224,11 @@ </message> <message> <source>About &Qt</source> - <translation>درباره و QT</translation> + <translation>درباره و Qt</translation> </message> <message> <source>Show information about Qt</source> - <translation>نمایش اطلاعات درباره QT</translation> + <translation>نمایش اطلاعات درباره Qt</translation> </message> <message> <source>&Options...</source> @@ -191,10 +247,6 @@ <translation>تغییر رمز/پَس فرِیز</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>اصلاح انتخابها برای پیکربندی Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>گرفتن نسخه پیشتیبان در آدرسی دیگر</translation> </message> @@ -255,15 +307,6 @@ <translation>تراکنش دریافتی</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>تاریخ: %1⏎ میزان وجه : %2⏎ نوع: %3⏎ آدرس: %4⏎ -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>wallet رمزگذاری شد و در حال حاضر از حالت قفل در آمده است</translation> </message> @@ -411,11 +454,7 @@ Address: %4 <source>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source> <translation>اطلاعات نمایش داده شده ممکن است روزآمد نباشد. wallet شما به صورت خودکار بعد از برقراری اتصال با شبکه bitcoin به روز می شود اما این فرایند هنوز تکمیل نشده است.</translation> </message> - <message> - <source>out of sync</source> - <translation>خارج از روزآمد سازی</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> </context> @@ -458,10 +497,6 @@ Address: %4 <source>Current number of blocks</source> <translation>تعداد زنجیره های حاضر</translation> </message> - <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>به کنسول آر.پی.سی. BITCOIN خوش آمدید</translation> - </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -609,10 +644,26 @@ Address: %4 <source>Message:</source> <translation>پیام:</translation> </message> - </context> + <message> + <source>Pay To:</source> + <translation>پرداخت به:</translation> + </message> + <message> + <source>Memo:</source> + <translation>یادداشت:</translation> + </message> +</context> <context> <name>ShutdownWindow</name> - </context> + <message> + <source>Bitcoin Core is shutting down...</source> + <translation>هسته بیت کوین در حال خاموش شدن است...</translation> + </message> + <message> + <source>Do not shut down the computer until this window disappears.</source> + <translation>تا پیش از بسته شدن این پنجره کامپیوتر خود را خاموش نکنید.</translation> + </message> +</context> <context> <name>SignVerifyMessageDialog</name> <message> @@ -707,10 +758,6 @@ Address: %4 <translation>گونه</translation> </message> <message> - <source>Address</source> - <translation>حساب</translation> - </message> - <message> <source>Open until %1</source> <translation>باز کن تا %1</translation> </message> @@ -727,6 +774,10 @@ Address: %4 <translation>تولید شده اما قبول نشده است</translation> </message> <message> + <source>Label</source> + <translation>برچسب</translation> + </message> + <message> <source>Received with</source> <translation>دریافت با</translation> </message> @@ -763,10 +814,6 @@ Address: %4 <translation>نوع تراکنش</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>آدرس مقصد در تراکنش</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>میزان وجه کم شده یا اضافه شده به حساب</translation> </message> @@ -846,6 +893,14 @@ Address: %4 <translation>برچسب را ویرایش کنید</translation> </message> <message> + <source>Exporting Failed</source> + <translation>صدور با شکست مواجه شد</translation> + </message> + <message> + <source>Exporting Successful</source> + <translation>صدور با موفقیت انجام شد</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Comma separated file (*.csv) فایل جداگانه دستوری</translation> </message> @@ -898,6 +953,10 @@ Address: %4 <context> <name>WalletView</name> <message> + <source>&Export</source> + <translation>صدور</translation> + </message> + <message> <source>Export the data in the current tab to a file</source> <translation>صدور داده نوار جاری به یک فایل</translation> </message> @@ -938,10 +997,22 @@ Address: %4 <translation>از تستِ شبکه استفاده نمایید</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>مبلغ تراکنش کمتر از آن است که پس از کسر هزینه تراکنش قابل ارسال باشد</translation> + </message> + <message> + <source>RPC server options:</source> + <translation>گزینه های سرویس دهنده RPC:</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>ارسال اطلاعات پیگیری/خطایابی به کنسول به جای ارسال به فایل debug.log</translation> </message> <message> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>ارسال تراکنش ها به صورت بدون کارمزد در صورت امکان (پیش فرض: %u)</translation> + </message> + <message> <source>Username for JSON-RPC connections</source> <translation>شناسه کاربری برای ارتباطاتِ JSON-RPC</translation> </message> @@ -982,6 +1053,22 @@ Address: %4 <translation>خطا در هنگام لود شدن wallet.dat</translation> </message> <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>تنظیم کمینه اندازه بلاک بر حسب بایت (پیش فرض: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <translation>تنظیم تعداد ریسمان ها برای سرویس دهی فراخوانی های RPC (پیش فرض: %d)</translation> + </message> + <message> + <source>Specify configuration file (default: %s)</source> + <translation>فایل تنظیمات را مشخص کنید (پیش فرض: %s)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>فایل pid را مشخص کنید (پیش فرض: %s)</translation> + </message> + <message> <source>Invalid amount for -paytxfee=<amount>: '%s'</source> <translation>میزان اشتباه است for -paytxfee=<amount>: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index c16e0e1776..eb90aa4281 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -1,9 +1,9 @@ -<TS language="fi" version="2.1"> +<TS language="fi" version="2.0"> <context> <name>AddressBookPage</name> <message> <source>Right-click to edit address or label</source> - <translation>Klikkaa hiiren oikealla painikkeella muokataksesi osoitetta tai nimikettä</translation> + <translation>Valitse hiiren oikealla painikkeella muokataksesi osoitetta tai nimikettä</translation> </message> <message> <source>Create a new address</source> @@ -27,7 +27,7 @@ </message> <message> <source>&Copy Address</source> - <translation>&Kopioi Osoite</translation> + <translation>&Kopioi osoite</translation> </message> <message> <source>Delete the currently selected address from the list</source> @@ -156,10 +156,6 @@ <translation>Vaihda tunnuslause</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Anna vanha ja uusi tunnuslause.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Vahvista lompakon salaus</translation> </message> @@ -172,6 +168,10 @@ <translation>Haluatko varmasti salata lompakkosi?</translation> </message> <message> + <source>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.</source> + <translation>Bitcoin Core sammuu nyt viimeistelläkseen kryptaamisen. Muista että lompakon kryptaaminen ei voi täysin suojata bitcoinejasi varkaudelta malwaren saastuttamalla tietokoneella.</translation> + </message> + <message> <source>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.</source> <translation>TÄRKEÄÄ: Kaikki vanhat lompakon varmuuskopiot pitäisi korvata uusilla suojatuilla varmuuskopioilla. Turvallisuussyistä edelliset varmuuskopiot muuttuvat turhiksi, kun aloitat suojatun lompakon käytön.</translation> </message> @@ -188,8 +188,8 @@ <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin sulkeutuu lopettaakseen salausprosessin. Muista, että salattukaan lompakko ei täysin suojaa sitä haittaohjelmien aiheuttamilta varkauksilta.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Syötä vanha ja uusi salasana lompakolle.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -264,7 +264,7 @@ </message> <message> <source>Show information about Qt</source> - <translation>Näytä tietoja QT:ta</translation> + <translation>Näytä tietoja Qt:ta</translation> </message> <message> <source>&Options...</source> @@ -311,10 +311,6 @@ <translation>Lähetä kolikoita Bitcoin-osoitteeseen</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Muuta Bitcoinin konfiguraatioasetuksia</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Varmuuskopioi lompakko toiseen sijaintiin</translation> </message> @@ -403,6 +399,10 @@ <translation>&Tietoja Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Muokkaa kokoonpanoasetuksia Bitcoin Corelle</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Näytä lähettämiseen käytettyjen osoitteiden ja nimien lista</translation> </message> @@ -431,6 +431,10 @@ <translation>Lohkojen lähdettä ei saatavilla...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Prosessoitu %n lohko rahansiirtohistoriasta.</numerusform><numerusform>Prosessoitu %n lohkoa rahansiirtohistoriasta.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n tunti</numerusform><numerusform>%n tuntia</numerusform></translation> </message> @@ -478,15 +482,41 @@ <source>Up to date</source> <translation>Rahansiirtohistoria on ajan tasalla</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>Käsitelty %n lohko rahansiirtohistoriasta.</numerusform><numerusform>Käsitelty %n lohkoa rahansiirtohistoriasta.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Saavutetaan verkkoa...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Päivämäärä: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Määrä: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tyyppi: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Nimike: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Osoite: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Lähetetyt rahansiirrot</translation> </message> @@ -495,17 +525,6 @@ <translation>Saapuva rahansiirto</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Päivä: %1 -Määrä: %2 -Tyyppi: %3 -Osoite: %4</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Lompakko on <b>salattu</b> ja tällä hetkellä <b>avoinna</b></translation> </message> @@ -696,6 +715,18 @@ Osoite: %4</translation> <translation>ei mitään</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Tämä nimi muuttuu punaiseksi mikäli rahansiirron koko on suurempi kuin 1000 tavua.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Tämä nimi muuttuu punaiseksi mikäli prioriteetti on pienempi kuin "medium".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Tämä nimike muuttuu punaiseksi mikäli mikä tahansa saaja vastaanottaa pienemmän määrän kuin %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Saattaa vaihdella +/- %1 satoshia per syöte.</translation> </message> @@ -708,10 +739,6 @@ Osoite: %4</translation> <translation>ei</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Tämä nimi muuttuu punaiseksi jos rahansiirron koko on suurempi kuin 1000 tavua</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Tämä tarkoittaa että vähintään %1 per kB palkkio on pakollinen.</translation> </message> @@ -724,14 +751,6 @@ Osoite: %4</translation> <translation>Rahansiirrot korkeammalla prioriteetilla sisällytetään varmemmin lohkoon.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Tämä nimi muuttuu punaiseksi jos prioriteetti on pienempi kuin "keskisuuri".</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Tämä nimi muuttuu punaiseksi jos vastaanottaja saa pienemmän määrän kuin %1</translation> - </message> - <message> <source>(no label)</source> <translation>(ei nimeä)</translation> </message> @@ -852,30 +871,6 @@ Osoite: %4</translation> <source>command-line options</source> <translation>komentorivi parametrit</translation> </message> - <message> - <source>UI options</source> - <translation>Käyttöliittymäasetukset</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Set language, for example "de_DE" (default: system locale)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Käynnistä pienennettynä</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Aseta SSL root varmenne maksupyynnöille (oletus: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Näytä aloitusruutu käynnistettäessä (oletus: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Valitse data-hakemisto käynnistyksessä (oletus: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -958,14 +953,6 @@ Osoite: %4</translation> <translation>&Yleiset</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Käynnistä Bitcoin kirjautumisen yhteydessä.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Käynnistä Bitcoin kirjautumisen yhteydessä</translation> - </message> - <message> <source>Size of &database cache</source> <translation>&Tietokannan välimuistin koko</translation> </message> @@ -1014,6 +1001,14 @@ Osoite: %4</translation> <translation>&Verkko</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Käynnistä Bitcoin Core automaattisesti järjestelmään kirjautumisen jälkeen.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Käynnistä Bitcoin Core järjestelmään kirjautuessa</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = jätä näin monta ydintä vapaaksi)</translation> </message> @@ -1078,10 +1073,6 @@ Osoite: %4</translation> <translation>&Pienennä ilmaisinalueelle työkalurivin sijasta</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Ikkunaa suljettaessa vain pienentää Bitcoin-ohjelman ikkunan lopettamatta itse ohjelmaa. Kun tämä asetus on valittuna, ohjelman voi sulkea vain valitsemalla Lopeta ohjelman valikosta.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>P&ienennä suljettaessa</translation> </message> @@ -1094,10 +1085,6 @@ Osoite: %4</translation> <translation>&Käyttöliittymän kieli</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Tässä voit määritellä käyttöliittymän kielen. Muutokset astuvat voimaan seuraavan kerran, kun Bitcoin käynnistetään.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>Yksikkö jona bitcoin-määrät näytetään</translation> </message> @@ -1134,8 +1121,8 @@ Osoite: %4</translation> <translation>Ohjelman uudelleenkäynnistys aktivoi muutokset.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Ohjelma lopetetaan. Haluatko jatkaa?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Asiakasohjelma sammutetaan. Haluatko jatkaa?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1220,10 +1207,6 @@ Osoite: %4</translation> <source>Current total balance in watch-only addresses</source> <translation>Nykyinen tase seurantaosoitetteissa</translation> </message> - <message> - <source>out of sync</source> - <translation>Ei ajan tasalla</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1244,10 +1227,6 @@ Osoite: %4</translation> <translation>Maksypyyntö verkossa ei täsmää asiakasohjelman verkkoon.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Maksupyyntö on vanhentunut.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Maksupyyntöä ei ole alustettu.</translation> </message> @@ -1276,14 +1255,30 @@ Osoite: %4</translation> <translation>Maksupyynnön tiedoston käsittely</translation> </message> <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>Maksupyynnön tiedostoa ei voida lukea! Tämä voi aiheutua sopimattomasta maksupyyntötiedostosta.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Maksupyyntö on vanhentunut.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Varmistamattomia maksupyyntöjä kustomoituun maksupalveluun ei tueta.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Epäkelpo maksupyyntö.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Maksupalautus %1:sta</translation> </message> <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>Maksupyyntö %1 on liian suuri (%2 tavua, sallittu %3 tavua).</translation> + </message> + <message> <source>Payment request DoS protection</source> <translation>Maksupyynnön DoS-suojaus</translation> </message> @@ -1292,6 +1287,10 @@ Osoite: %4</translation> <translation>Virhe kommunikoidessa %1n kanssa: %2</translation> </message> <message> + <source>Payment request cannot be parsed!</source> + <translation>Maksupyyntöä ei voida jäsentää!</translation> + </message> + <message> <source>Bad response from server %1</source> <translation>Huono vastaus palvelimelta %1</translation> </message> @@ -1311,8 +1310,8 @@ Osoite: %4</translation> <translation>Käyttöliittymä</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Osoite/Isäntänimi</translation> + <source>Node/Service</source> + <translation>Noodi/Palvelu</translation> </message> <message> <source>Ping Time</source> @@ -1346,14 +1345,6 @@ Osoite: %4</translation> <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>VERKKO</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>TUNNISTAMATON</translation> - </message> - <message> <source>None</source> <translation>Ei yhtään</translation> </message> @@ -1512,6 +1503,10 @@ Osoite: %4</translation> <translation>Vasteaika</translation> </message> <message> + <source>Time Offset</source> + <translation>Ajan poikkeama</translation> + </message> + <message> <source>Last block time</source> <translation>Viimeisimmän lohkon aika</translation> </message> @@ -1552,16 +1547,12 @@ Osoite: %4</translation> <translation>Debug lokitiedosto</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Avaa lokitiedosto nykyisestä data-kansiosta. Tämä voi viedä useamman sekunnin, jos lokitiedosto on iso.</translation> - </message> - <message> <source>Clear console</source> <translation>Tyhjennä konsoli</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Tervetuloa Bitcoin RPC konsoliin.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Tervetuloa Bitcoin Coren RPC-konsoliin.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1852,14 +1843,14 @@ Osoite: %4</translation> <translation>pudota kulujen asetukset</translation> </message> <message> - <source>Minimize</source> - <translation>Pienennä</translation> - </message> - <message> <source>per kilobyte</source> <translation>per kilotavu</translation> </message> <message> + <source>Hide</source> + <translation>Piilota</translation> + </message> + <message> <source>total at least</source> <translation>yhteensä ainakin</translation> </message> @@ -1972,10 +1963,6 @@ Osoite: %4</translation> <translation>tai</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Vastaanottajan osoite on virheellinen. Tarkista osoite.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Maksettavan summan tulee olla suurempi kuin 0 Bitcoinia.</translation> </message> @@ -1988,10 +1975,6 @@ Osoite: %4</translation> <translation>Kokonaismäärä ylittää saldosi kun %1 maksukulu lisätään summaan.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Sama osoite toistuu useamman kerran. Samaan osoitteeseen voi lähettää vain kerran per maksu.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Rahansiirron luonti epäonnistui!</translation> </message> @@ -2000,10 +1983,22 @@ Osoite: %4</translation> <translation>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ä.</translation> </message> <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Rahansiirtokulua %1 ja sitä suurempia määriä pidetään järjenvastaisen korkeana kuluna.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Maksupyyntö on vanhentunut.</translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Maksa vain vähimmäiskulu %1</translation> </message> <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Vastaanottajan osoite ei ole kelvollinen. Tarkistathan uudelleen.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Varoitus: Virheellinen Bitcoin osoite</translation> </message> @@ -2075,12 +2070,20 @@ Osoite: %4</translation> <translation>Poista tämä alkio</translation> </message> <message> + <source>S&ubtract fee from amount</source> + <translation>V&ähennä maksukulu määrästä</translation> + </message> + <message> <source>Message:</source> <translation>Viesti:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Tämä on varmistettu maksupyyntö.</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Tämä on todentamaton maksupyyntö.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Tämä on todennettu maksupyyntö.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2091,10 +2094,6 @@ Osoite: %4</translation> <translation>Viesti joka liitettiin bitcoin: URI:iin tallennetaan rahansiirtoon viitteeksi. Tätä viestiä ei lähetetä Bitcoin-verkkoon.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Tämä on varmistamaton maksupyyntö</translation> - </message> - <message> <source>Pay To:</source> <translation>Saaja:</translation> </message> @@ -2125,10 +2124,6 @@ Osoite: %4</translation> <translation>&Allekirjoita viesti</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Voit allekirjoittaa viestit omalla osoitteellasi todistaaksesi että omistat ne. Ole huolellinen, että et allekirjoita mitään epämääräistä, phishing-hyökkääjät voivat huijata sinua allekirjoittamaan luovuttamalla henkilöllisyytesi. Allekirjoita selvitys täysin yksityiskohtaisesti mihin olet sitoutunut.</translation> - </message> - <message> <source>The Bitcoin address to sign the message with</source> <translation>Bitcoin-osoite jolla viesti allekirjoitetaan</translation> </message> @@ -2181,10 +2176,6 @@ Osoite: %4</translation> <translation>&Varmista viesti</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Syötä allekirjoittava osoite, viesti ja allekirjoitus alla oleviin kenttiin varmistaaksesi allekirjoituksen aitouden. Varmista että kopioit kaikki kentät täsmälleen oikein, myös rivinvaihdot, välilyönnit, tabulaattorit, jne.</translation> - </message> - <message> <source>The Bitcoin address the message was signed with</source> <translation>Bitcoin-osoite jolla viesti on allekirjoitettu</translation> </message> @@ -2448,10 +2439,6 @@ Osoite: %4</translation> <translation>Laatu</translation> </message> <message> - <source>Address</source> - <translation>Osoite</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Epäkypsä (%1 varmistusta, saatavilla %2 jälkeen)</translation> </message> @@ -2480,6 +2467,10 @@ Osoite: %4</translation> <translation>Offline</translation> </message> <message> + <source>Label</source> + <translation>Nimi</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Varmistamaton</translation> </message> @@ -2532,8 +2523,8 @@ Osoite: %4</translation> <translation>Rahansiirron laatu.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Rahansiirron kohteen Bitcoin-osoite</translation> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Onko rahansiirrossa mukana ainoastaan katseltava osoite vai ei.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2778,18 +2769,10 @@ Osoite: %4</translation> <translation>Kytkeydy annettuun osoitteeseen ja pidä linja aina auki. Käytä [host]:portin merkintätapaa IPv6:lle.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Aloita regression testimoodi joka käyttää erikoisketjua jossa lohkoja voidaan ratkaista välittömästi.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Suorita käsky kun lompakossa rahansiirto muuttuu (%s cmd on vaihdettu TxID kanssa)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>Tässä moodissa -genproclimit ohjaa kuinka monta lohkoa luodaan välittömästi.</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>Aseta script varmistuksen threadien lukumäärä (%u - %d, 0= auto, <0 = jätä näin monta ydintä vapaaksi, oletus: %d)</translation> </message> @@ -2854,10 +2837,6 @@ Osoite: %4</translation> <translation>Debuggaus/Testauksen valinnat:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Hae oma IP osoite (vakioasetus: 1 kun kuuntelemassa ja ei -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Älä lataa lompakkoa ja poista lompakon RPC kutsut</translation> </message> @@ -2882,6 +2861,10 @@ Osoite: %4</translation> <translation>Virhe avattaessa lohkoindeksiä</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Virhe: Sisäinen kriittinen virhe kohdattiin, katso debug.log:sta lisätietoja</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Varoitus: Levytila on vähissä!</translation> </message> @@ -2910,8 +2893,12 @@ Osoite: %4</translation> <translation>Ei tarpeeksi tiedostomerkintöjä vapaana.</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Uudelleenrakenna lohkoketjuindeksi nykyisistä blk000??.dat tiedostoista</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>Yhdistä vain solmukohtiin <net>-verkossa (ipv4, ipv6 tai onion)</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Karsittu tila ei ole yhteensopiva -txindex:n kanssa.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2926,10 +2913,6 @@ Osoite: %4</translation> <translation>Aseta lompakkotiedosto (data-hakemiston sisällä)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Tämä on tarkoitettu regression testityökaluille ja ohjelman kehittämiseen.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Käytä UPnP:ta kuuntelevan portin kartoittamiseen (oletus: %u)</translation> </message> @@ -2950,6 +2933,10 @@ Osoite: %4</translation> <translation>Lompakon valinnat:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Varoitus: Tämä versio on vanhentunut; päivittämistä vaaditaan!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Sinun tulee uudelleenrakentaa tietokanta käyttäen -reindex vaihtaen -txindex</translation> </message> @@ -2974,6 +2961,30 @@ Osoite: %4</translation> <translation>Aseta kolikoiden luomiseen tarkoitettujen säikeiden lukumäärä (-1 = kaikki ytimet, oletus: %d)</translation> </message> <message> + <source>(default: %u)</source> + <translation>(oletus: %u)</translation> + </message> + <message> + <source>Accept public REST requests (default: %u)</source> + <translation>Hyväksy julkisia REST-pyyntöjä (oletus: %u)</translation> + </message> + <message> + <source>Activating best chain...</source> + <translation>Aktivoidaan parhainta ketjua...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Lompakkoa ei voida ajaa karsitussa tilassa.</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>-whitebind -osoitetta '%s' ei voida jäsentää</translation> + </message> + <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Valitse data-hakemisto käynnistyksessä (oletus: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Yhdistä SOCKS5 proxin kautta</translation> </message> @@ -2986,6 +2997,10 @@ Osoite: %4</translation> <translation>Virhe ladattaessa wallet.dat-tiedostoa: Tarvitset uudemman version Bitcoinista</translation> </message> <message> + <source>Error reading from database, shutting down.</source> + <translation>Virheitä tietokantaa luettaessa, ohjelma pysäytetään.</translation> + </message> + <message> <source>Information</source> <translation>Tietoa</translation> </message> @@ -3010,22 +3025,34 @@ Osoite: %4</translation> <translation>RPC-palvelimen valinnat:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Satunnaisesti pudota 1 joka <n> verkkoviestistä</translation> + <source>RPC support for HTTP persistent connections (default: %d)</source> + <translation>RPC-tuki pysyville HTTP-yhteyksille (oletus: %d)</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Satunnaisesti sekoita 1 joka <n> verkkoviestistä</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Vastaanota ja näytä P2P-verkon hälytyksiä (oletus: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Lähetä jäljitys/debug-tieto konsoliin, debug.log-tiedoston sijaan</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Aseta SSL root varmenne maksupyynnöille (oletus: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Set language, for example "de_DE" (default: system locale)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Näytä kaikki debuggaus valinnat: (käyttö: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Näytä aloitusruutu käynnistettäessä (oletus: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Pienennä debug.log tiedosto käynnistyksen yhteydessä (vakioasetus: 1 kun ei -debug)</translation> </message> @@ -3034,6 +3061,10 @@ Osoite: %4</translation> <translation>Siirron vahvistus epäonnistui</translation> </message> <message> + <source>Start minimized</source> + <translation>Käynnistä pienennettynä</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Tämä on ohjelmistoa kokeelliseen käyttöön.</translation> </message> @@ -3050,6 +3081,10 @@ Osoite: %4</translation> <translation>Siirtosumma liian iso</translation> </message> <message> + <source>UI Options:</source> + <translation>Ulkoasun asetukset:</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Käytä UPnP:tä kuunneltavan portin avaamiseen (vakioasetus: 1 kun kuuntelemassa)</translation> </message> @@ -3066,10 +3101,6 @@ Osoite: %4</translation> <translation>Varoitus</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Varoitus: Tämä versio on vanhentunut, päivitys tarpeen!</translation> - </message> - <message> <source>Zapping all transactions from wallet...</source> <translation>Tyhjennetään kaikki rahansiirrot lompakosta....</translation> </message> @@ -3118,6 +3149,10 @@ Osoite: %4</translation> <translation>Virhe ladattaessa wallet.dat-tiedostoa: Lompakko vioittunut</translation> </message> <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Käytä erillistä SOCKS5-proxyä tavoittaaksesi vertaisia Tor-piilopalveluiden kautta (oletus: %s)</translation> + </message> + <message> <source>(default: %s)</source> <translation>(oletus: %s)</translation> </message> @@ -3130,10 +3165,6 @@ Osoite: %4</translation> <translation>Virhe ladattaessa wallet.dat-tiedostoa</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Pakota yhteensopivuustila (oletus: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Luo kolikoita (oletus: %u)</translation> </message> @@ -3150,6 +3181,14 @@ Osoite: %4</translation> <translation>Virheellinen proxy-osoite '%s'</translation> </message> <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Kuuntele yhteyksiä portissa <port> (oletus: %u tai testnet: %u)</translation> + </message> + <message> + <source>Make the wallet broadcast transactions</source> + <translation>Aseta lompakko kuuluttamaan rahansiirtoja</translation> + </message> + <message> <source>Relay non-P2SH multisig (default: %u)</source> <translation>Välitä ei-P2SH-multisig (oletus: %u)</translation> </message> @@ -3182,6 +3221,10 @@ Osoite: %4</translation> <translation>Määritä pid-tiedosto (oletus: %s)</translation> </message> <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <translation>Käytä vahvistamattomia vaihtorahoja lähetettäessä rahansiirtoja (oletus: %u)</translation> + </message> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Tuntematon verkko -onlynet parametrina: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index df0c507a44..fe140634e6 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -1,4 +1,4 @@ -<TS language="fr" version="2.1"> +<TS language="fr" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ <translation>Changer la phrase de passe</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Saisir l’ancienne phrase de passe pour le portefeuille ainsi que la nouvelle.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Confirmer le chiffrement du portefeuille</translation> </message> @@ -172,6 +168,10 @@ <translation>Êtes-vous sûr de vouloir chiffrer votre portefeuille ?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>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é.</translation> </message> @@ -188,8 +188,8 @@ <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin va à présent se fermer pour terminer le chiffrement. N'oubliez pas que le chiffrement de votre portefeuille n'est pas une protection totale contre le vol par des logiciels malveillants qui infecteraient votre ordinateur.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Saisir l'ancienne phrase de passe puis la nouvelle phrase de passe du portefeuille.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>Envoyer des pièces à une adresse Bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Modifier les options de configuration de Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Sauvegarder le portefeuille vers un autre emplacement</translation> </message> @@ -403,6 +399,10 @@ <translation>À &propos de Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modifier les options de configuration de Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Afficher la liste d'adresses d'envoi et d'étiquettes utilisées</translation> </message> @@ -431,6 +431,10 @@ <translation>Aucune source de blocs disponible...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>%n bloc d'historique transactionnel a été traité</numerusform><numerusform>%n blocs d'historique transactionnel ont été traités</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n heure</numerusform><numerusform>%n heures</numerusform></translation> </message> @@ -478,35 +482,49 @@ <source>Up to date</source> <translation>À jour</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>%n bloc de l'historique transactionnel a été traité</numerusform><numerusform>%n blocs de l'historique transactionnel ont été traités</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Rattrapage en cours…</translation> </message> <message> - <source>Sent transaction</source> - <translation>Transaction envoyée</translation> + <source>Date: %1 +</source> + <translation>Date : %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Transaction entrante</translation> + <source>Amount: %1 +</source> + <translation>Montant : %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 +</source> + <translation>Type : %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Étiquette : %1 +</translation> + </message> + <message> + <source>Address: %1 </source> - <translation>Date : %1 -Montant : %2 -Type : %3 -Adresse : %4 + <translation>Adresse : %1 </translation> </message> <message> + <source>Sent transaction</source> + <translation>Transaction envoyée</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Transaction entrante</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Le portefeuille est <b>chiffré</b> et est actuellement <b>déverrouillé</b></translation> </message> @@ -697,6 +715,14 @@ Adresse : %4 <translation>aucun</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Cette étiquette devient rouge si la taille de la transaction est plus grande que 1 000 octets.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Cette étiquette devient rouge si la priorité est plus basse que « moyenne ».</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Peut varier +/- %1 satoshi(s) par entrée.</translation> </message> @@ -709,10 +735,6 @@ Adresse : %4 <translation>non</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Cette étiquette devient rouge si la taille de la transaction est plus grande que 1 000 octets.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Ceci signifie que des frais d'au moins %1 par ko sont exigés.</translation> </message> @@ -725,10 +747,6 @@ Adresse : %4 <translation>Les transactions à priorité plus haute sont plus à même d'être incluses dans un bloc.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Cette étiquette devient rouge si la priorité est plus basse que « moyenne »</translation> - </message> - <message> <source>(no label)</source> <translation>(aucune étiquette)</translation> </message> @@ -849,30 +867,6 @@ Adresse : %4 <source>command-line options</source> <translation>options de ligne de commande</translation> </message> - <message> - <source>UI options</source> - <translation>Options de l'interface utilisateur</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Définir la langue, par exemple « fr_CA » (par défaut : la langue du système)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Démarrer minimisé</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Définir les certificats SSL racine pour les requêtes de paiement (par défaut : -système-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Afficher l'écran d'accueil au démarrage (par défaut : 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Choisir un répertoire de données au démarrage (par défaut : 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -951,14 +945,6 @@ Adresse : %4 <translation>Réglages &principaux</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Démarrer Bitcoin automatiquement après avoir ouvert une session sur l'ordinateur.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Démarrer Bitcoin lors de l'ouverture d'une session</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Taille du cache de la base de &données</translation> </message> @@ -983,6 +969,14 @@ Adresse : %4 <translation>Adresse IP du mandataire (par ex. IPv4 : 127.0.0.1 / IPv6 : ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>La langue de l'interface utilisateur peut être définie ici. Ce réglage sera pris en compte après redémarrage de Bitcoin.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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 |.</translation> </message> @@ -1007,6 +1001,14 @@ Adresse : %4 <translation>&Réseau</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Démarrer Bitcoin Core automatiquement après avoir ouvert une session sur le système.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Démarrer Bitcoin Core lors de l'ouverture d'une session</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, < 0 = laisser ce nombre de cœurs inutilisés)</translation> </message> @@ -1071,10 +1073,6 @@ Adresse : %4 <translation>&Minimiser dans la barre système au lieu de la barre des tâches</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimiser au lieu de quitter l'application lorsque la fenêtre est fermée. Si cette option est activée, l'application ne pourra être fermée qu'en sélectionnant Quitter dans le menu.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimiser lors de la fermeture</translation> </message> @@ -1087,10 +1085,6 @@ Adresse : %4 <translation>&Langue de l'interface utilisateur :</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>La langue de l'interface utilisateur peut être définie ici. Ce réglage sera pris en compte après redémarrage de Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Unité d'affichage des montants :</translation> </message> @@ -1127,8 +1121,8 @@ Adresse : %4 <translation>Le redémarrage du client est nécessaire pour activer les changements.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Le client sera arrêté, voulez-vous continuer?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Le client sera arrêté. Voulez-vous continuer ?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1213,10 +1207,6 @@ Adresse : %4 <source>Current total balance in watch-only addresses</source> <translation>Solde total actuel dans des adresses juste-regarder</translation> </message> - <message> - <source>out of sync</source> - <translation>désynchronisé</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1237,10 +1227,6 @@ Adresse : %4 <translation>Le réseau de la demande de paiement ne correspond pas au réseau du client.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>La demande de paiement est expirée.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>La demande de paiement n'est pas initialisée.</translation> </message> @@ -1273,10 +1259,18 @@ Adresse : %4 <translation>Le fichier de demande de paiement ne peut pas être lu ! Ceci peut être causé par un fichier de demande de paiement invalide.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Demande de paiement expirée.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Les demandes de paiements non vérifiées à des scripts de paiement personnalisés ne sont pas prises en charge.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Demande de paiement invalide.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Remboursement de %1</translation> </message> @@ -1316,8 +1310,8 @@ Adresse : %4 <translation>Agent utilisateur</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Adresse/nom d'hôte</translation> + <source>Node/Service</source> + <translation>Nœud/service</translation> </message> <message> <source>Ping Time</source> @@ -1351,14 +1345,6 @@ Adresse : %4 <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>RÉSEAU</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>INCONNU</translation> - </message> - <message> <source>None</source> <translation>Aucun</translation> </message> @@ -1449,6 +1435,10 @@ Adresse : %4 <translation>Nombre actuel de blocs</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Ouvrir le journal de débogage du répertoire de données actuel. Ceci pourrait prendre quelques secondes pour les gros fichiers de journalisation.</translation> + </message> + <message> <source>Received</source> <translation>Reçu</translation> </message> @@ -1517,6 +1507,10 @@ Adresse : %4 <translation>Temps de ping</translation> </message> <message> + <source>Time Offset</source> + <translation>Décalage temporel</translation> + </message> + <message> <source>Last block time</source> <translation>Horodatage du dernier bloc</translation> </message> @@ -1557,16 +1551,12 @@ Adresse : %4 <translation>Journal de débogage</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Ouvrir le journal de débogage de Bitcoin depuis le répertoire de données actuel. Ceci peut prendre quelques secondes pour les journaux de grande taille.</translation> - </message> - <message> <source>Clear console</source> <translation>Nettoyer la console</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Bienvenue sur la console RPC de Bitcoin.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Bienvenue dans le console RPC de Bitcoin Core.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1857,14 +1847,6 @@ Adresse : %4 <translation>réduire les paramètres des frais</translation> </message> <message> - <source>Minimize</source> - <translation>Minimiser</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Si les frais personnalisés sont définis à 1 000 satoshis et que la transaction est seulement de 250 octets, donc le « par kilo-octet » ne paiera que 250 satoshis de frais, alors que le « au moins » paiera 1 000 satoshis. Pour des transactions supérieures à un kilo-octet, les deux paieront par kilo-octets.</translation> - </message> - <message> <source>per kilobyte</source> <translation>par kilo-octet</translation> </message> @@ -1873,6 +1855,10 @@ Adresse : %4 <translation>Si les frais personnalisés sont définis à 1 000 satoshis et que la transaction est seulement de 250 octets, donc le « par kilo-octet » ne paiera que 250 satoshis de frais, alors que le « total au moins » paiera 1 000 satoshis. Pour des transactions supérieures à un kilo-octet, les deux paieront par kilo-octets.</translation> </message> <message> + <source>Hide</source> + <translation>Cacher</translation> + </message> + <message> <source>total at least</source> <translation>total au moins</translation> </message> @@ -1993,10 +1979,6 @@ Adresse : %4 <translation>ou</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>L'adresse du destinataire n’est pas valide, veuillez la vérifier.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Le montant à payer doit être supérieur à 0.</translation> </message> @@ -2009,10 +1991,6 @@ Adresse : %4 <translation>Le montant dépasse votre solde lorsque les frais de transaction de %1 sont inclus.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Adresse indentique trouvée, il n'est possible d'envoyer qu'une fois à chaque adresse par opération d'envoi.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>La création de la transaction a échoué !</translation> </message> @@ -2021,16 +1999,28 @@ Adresse : %4 <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> - <translation>Des frais supérieurs à %1 sont considérés comme follement élevés.</translation> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Des frais supérieurs à %1 sont considérés comme ridiculement élevés.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Demande de paiement expirée.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Il est estimé que la confirmation commencera dans %n bloc.</numerusform><numerusform>Il est estimé que la confirmation commencera dans %n blocs.</numerusform></translation> </message> <message> <source>Pay only the minimum fee of %1</source> <translation>Payer seulement les frais minimum de %1</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Début de confirmation estimé à %1 bloc(s).</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>L'adresse du destinataire est invalide. Veuillez la vérifier.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Adresse identique trouvée : chaque adresse ne devrait être utilisée qu'une fois.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2104,12 +2094,24 @@ Adresse : %4 <translation>Enlever cette entrée</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>Les frais seront déduits du montant envoyé. Le destinataire recevra moins de bitcoins que le montant saisi dans le champ de montant. Si plusieurs destinataires sont sélectionnés, les frais seront partagés également..</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>S&oustraire les frais du montant</translation> + </message> + <message> <source>Message:</source> <translation>Message :</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Ceci est une demande de paiement vérifiée.</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Cette demande de paiement n'est pas authentifiée.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Cette demande de paiement est authentifiée.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2120,10 +2122,6 @@ Adresse : %4 <translation>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.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Ceci est une demande de paiement non vérifiée.</translation> - </message> - <message> <source>Pay To:</source> <translation>Payer à :</translation> </message> @@ -2154,8 +2152,8 @@ Adresse : %4 <translation>&Signer un message</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Vous pouvez signer des messages avec vos adresses pour prouver que vous les détenez. Faites attention de ne pas signer de vague car des attaques d'hameçonnage peuvent essayer d'usurper votre identité par votre signature. Ne signez que des déclarations entièrement détaillées et avec lesquelles vous serez d'accord.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>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.</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2210,8 +2208,8 @@ Adresse : %4 <translation>&Vérifier un message</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Saisir ci-dessous l'adresse de signature, le message (assurez-vous d'avoir copié exactement les retours à la ligne, les espaces, 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é lui-même pour éviter d'être trompé par une attaque d'homme du milieu.</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>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.</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2477,10 +2475,6 @@ Adresse : %4 <translation>Type</translation> </message> <message> - <source>Address</source> - <translation>Adresse</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Immature (%1 confirmations, sera disponible après %2)</translation> </message> @@ -2509,6 +2503,10 @@ Adresse : %4 <translation>Hors ligne</translation> </message> <message> + <source>Label</source> + <translation>Étiquette</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Non confirmé</translation> </message> @@ -2565,8 +2563,8 @@ Adresse : %4 <translation>Une adresse juste-regarder est-elle impliquée dans cette transaction.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>L’adresse de destination de la transaction.</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Intention/but de la transaction défini par l'utilisateur.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2819,16 +2817,16 @@ Adresse : %4 <translation>Distribué sous la licence MIT d'utilisation d'un logiciel. Consultez le fichier joint COPYING ou <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Passer en mode de test de régression qui utilise une chaîne spéciale dans laquelle les blocs sont résolus instantanément.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Exécuter la commande lorsqu'une transaction de portefeuille change (%s dans la commande est remplacée par TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>Dans ce mode -genproclimit contrôle combien de blocs sont générés immédiatement.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Total maximal des frais à utiliser en une seule transaction de portefeuille. Le définir trop bas pourrait interrompre les grosses transactions (par défaut : %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Réduire les exigences de stockage en élaguant (supprimant) les anciens blocs. Ce mode désactive la prise en charge de portefeuilles et n'est pas compatible avec -txindex. Avertissement : configurer ce paramètre à sa valeur antérieure retéléchargera complètement la chaîne de blocs (par défaut : 0 = désactiver l'élagage des blocs, >%u = taille cible en Mo à utiliser pour les fichiers de blocs).</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2843,6 +2841,14 @@ Adresse : %4 <translation>Impossible de se lier à %s sur cet ordinateur. Bitcoin Core fonctionne probablement déjà.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVERTISSEMENT : un nombre anormalement élevé de blocs a été généré, %d blocs reçus durant les %d dernières heures (%d attendus)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVERTISSEMENT : vérifiez votre connexion réseau, %d blocs reçus durant les %d dernières heures (%d attendus)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Avertissement : -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.</translation> </message> @@ -2899,10 +2905,6 @@ Adresse : %4 <translation>Options de test/de débogage :</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Découvrir sa propre adresse IP (par défaut : 1 lors de l'écoute et si aucun -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Ne pas charger le portefeuille et désactiver les appels RPC</translation> </message> @@ -2963,8 +2965,12 @@ Adresse : %4 <translation>Seulement se connecter aux nœuds du réseau <net> (IPv4, IPv6 ou oignon)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Reconstruire l'index de la chaîne de blocs à partir des fichiers blk000??.dat courants</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>L'élagage ne peut pas être configuré avec une valeur négative.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Le mode élagage n'est pas compatible avec -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2979,10 +2985,6 @@ Adresse : %4 <translation>Spécifiez le fichier de portefeuille (dans le répertoire de données)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Ceci est à l'intention des outils de test de régression et du développement applicatif.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Utiliser l'UPnP pour mapper le port d'écoute (par défaut : %u)</translation> </message> @@ -3003,6 +3005,10 @@ Adresse : %4 <translation>Options du portefeuille :</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Avertissement : cette version est obsolète. Une mise à niveau est exigée !</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Vous devez reconstruire la base de données en utilisant -reindex afin de modifier -txindex</translation> </message> @@ -3031,14 +3037,14 @@ Adresse : %4 <translation>Impossible d’obtenir un verrou sur le répertoire de données %s. Bitcoin Core fonctionne probablement déjà.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Limiter continuellement les transactions gratuites à <n>*1000 octets par minute (par défaut : %u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>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)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Découvrir ses propres adresses (par défaut : 1 en écoute et sans externalip ou -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Erreur : l'écoute des connexions entrantes a échoué (l'écoute a retourné l'erreur %s)</translation> </message> @@ -3055,10 +3061,6 @@ Adresse : %4 <translation>Les frais (en BTC/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour le relayage (par défaut : %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Les frais (en BTC/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour la création de transactions (par défaut : %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>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)</translation> </message> @@ -3071,14 +3073,18 @@ Adresse : %4 <translation>Quantité maximale de données dans les transactions du porteur de données que nous relayons et minons (par défaut : %u)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>Total maximal des frais à utiliser en une seule transaction de portefeuille. Le définir trop bas pourrait empêcher les grosses transactions (par défaut : %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>L'élagage est configuré au-dessous du minimum de %d Mo. Veuillez utiliser un nombre plus élevé.</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Demander les adresses des pairs par recherche DNS si l'on manque d'adresses (par défaut : 1 sauf si -connect)</translation> </message> <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Aléer les authentifiants pour chaque connexion mandataire. Ceci active l'isolement de flux de Tor (par défaut : %u) </translation> + </message> + <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Définir la taille maximale en octets des transactions prioritaires/à frais modiques (par défaut : %d)</translation> </message> @@ -3087,6 +3093,10 @@ Adresse : %4 <translation>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)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Le montant de la transaction est trop bas pour être envoyé une fois que les frais ont été déduits</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -3127,14 +3137,34 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>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</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>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.</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(par défaut : %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Accepter les demandes REST publiques (par défaut : %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Activation de la meilleure chaîne...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>L'exécution est impossible quand le portefeuille est en mode élagage.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Impossible de résoudre l'adresse -whitebind : « %s »</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Choisir un répertoire de données au démarrage (par défaut : 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Se connecter par un mandataire SOCKS5</translation> </message> @@ -3215,12 +3245,12 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Prise en charge de RPC pour les connexions persistantes HTTP (par défaut : %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Abandonner aléatoirement 1 message du réseau sur <n></translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Reconstruire au démarrage l'index de la chaîne de blocs à partir des fichiers blk000??.dat actuels</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Tester aléatoirement 1 message du réseau sur <n></translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Recevoir et afficher les alertes du réseau poste à poste (%u par défaut)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3231,10 +3261,22 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Envoyer si possible les transactions comme étant sans frais (par défaut : %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Définir les certificats racine SSL pour les demandes de paiement (par défaut : -système-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Définir la langue, par exemple « fr_CA » (par défaut : la langue du système)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Montrer toutes les options de débogage (utilisation : --help --help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Afficher la page de garde au démarrage (par défaut : 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Réduire le fichier debug.log lors du démarrage du client (par défaut : 1 lorsque -debug n'est pas présent)</translation> </message> @@ -3243,6 +3285,14 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>La signature de la transaction a échoué</translation> </message> <message> + <source>Start minimized</source> + <translation>Démarrer minimisé</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Le montant de la transaction est trop bas pour que les frais soient payés</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Ceci est un logiciel expérimental.</translation> </message> @@ -3263,6 +3313,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Transaction trop volumineuse</translation> </message> <message> + <source>UI Options:</source> + <translation>Options de l'IU :</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Impossible de se lier à %s sur cet ordinateur (bind a retourné l'erreur %s)</translation> </message> @@ -3283,10 +3337,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Avertissement</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Avertissement : cette version est obsolète, une mise à niveau est nécessaire !</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Avertissement : l'argument -benchmark non pris en charge a été ignoré, utiliser -debug=bench.</translation> </message> @@ -3347,18 +3397,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>(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)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Purger l’activité de la base de données de la zone de mémoire vers le journal sur disque tous les <n> mégaoctets (par défaut : %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Degré de profondeur de la vérification des blocs -checkblocks (0-4, par défaut : %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Lors du minage, journaliser la priorité des transactions et les frais par ko (par défaut : %u) </translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Maintenir un index complet des transactions, utilisé par l'appel RPC getrawtransaction (obtenir la transaction brute) (par défaut : %u)</translation> </message> @@ -3387,18 +3429,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Toujours demander les adresses des pairs par recherche DNS (par défaut : %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Désactiver le mode sans échec, passer outre un événement sans échec réel (par défaut : %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Erreur lors du chargement de wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Forcer le mode sans échec (par défaut : %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Générer des pièces (défaut : %u)</translation> </message> @@ -3415,10 +3449,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Adresse -proxy invalide : « %s »</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Limiter la taille du cache des signatures à <n> entrées (par défaut : %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Écouter les connexions JSON-RPC sur <port> (par défaut : %u ou tesnet : %u)</translation> </message> @@ -3431,6 +3461,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Garder au plus <n> connexions avec les pairs (par défaut : %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Obliger le portefeuille à diffuser les transactions</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Tampon maximal de réception par connexion, <n>*1000 octets (par défaut : %u)</translation> </message> @@ -3439,10 +3473,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Tampon maximal d'envoi par connexion », <n>*1000 octets (par défaut : %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>N'accepter qu'une chaîne de blocs correspondant aux points de vérification intégrés (par défaut : %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Ajouter l'horodatage au début de la sortie de débogage (par défaut : %u)</translation> </message> @@ -3455,10 +3485,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Relayer les multisignatures non-P2SH (par défaut : %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Exécuter une tâche pour purger le portefeuille périodiquement (par défaut : %u) </translation> - </message> - <message> <source>Set key pool size to <n> (default: %u)</source> <translation>Définir la taille de la réserve de clefs à <n> (par défaut : %u)</translation> </message> @@ -3467,10 +3493,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Définir la taille de bloc minimale en octets (par défaut : %u)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Définit le drapeau DB_PRIVATE dans l'environnement de la BD du portefeuille (par défaut : %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Spécifier le fichier de configuration (par défaut : %s)</translation> </message> @@ -3487,10 +3509,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Dépenser la monnaie non confirmée lors de l'envoi de transactions (par défaut : %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Cesser l'exécution après l'importation des blocs du disque (par défaut : %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Seuil de déconnexion des pairs présentant un mauvais comportement (par défaut : %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_fr_CA.ts b/src/qt/locale/bitcoin_fr_CA.ts index f314f3d1c1..f4fe7d6597 100644 --- a/src/qt/locale/bitcoin_fr_CA.ts +++ b/src/qt/locale/bitcoin_fr_CA.ts @@ -1,4 +1,4 @@ -<TS language="fr_CA" version="2.1"> +<TS language="fr_CA" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -169,8 +169,8 @@ <context> <name>TransactionTableModel</name> <message> - <source>Address</source> - <translation>Addresse</translation> + <source>Label</source> + <translation>Record</translation> </message> </context> <context> diff --git a/src/qt/locale/bitcoin_gl.ts b/src/qt/locale/bitcoin_gl.ts index ac2d7087a4..709b17e2f7 100644 --- a/src/qt/locale/bitcoin_gl.ts +++ b/src/qt/locale/bitcoin_gl.ts @@ -1,4 +1,4 @@ -<TS language="gl" version="2.1"> +<TS language="gl" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -148,10 +148,6 @@ <translation>Cambiar contrasinal</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Introduce o vello e novo contrasinais no moedeiro.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Confirmar encriptación de moedeiro</translation> </message> @@ -176,10 +172,6 @@ <translation>Moedeiro encriptado</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin se pechará agora para rematar o proceso de encriptación. Lembra que encriptar o teu moedeiro non protexe totalmente os teus bitcoins de ser robados por malware que infecte o teu ordenador.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>Encriptación de moedeiro fallida</translation> </message> @@ -279,10 +271,6 @@ <translation>Enviar moedas a unha dirección Bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Modificar opcións de configuración para Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Facer copia de seguridade do moedeiro noutra localización</translation> </message> @@ -378,26 +366,10 @@ <source>Open a bitcoin: URI or payment request</source> <translation>Abrir un bitcoin: URI ou solicitude de pago</translation> </message> - <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n conexión activa coa rede Bitcoin</numerusform><numerusform>%n conexións activas coa rede Bitcoin</numerusform></translation> - </message> <message> <source>No block source available...</source> <translation>Non hai orixe de bloques dispoñible...</translation> </message> - <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n día</numerusform><numerusform>%n días</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n week(s)</source> - <translation><numerusform>%n semana</numerusform><numerusform>%n semanas</numerusform></translation> - </message> <message> <source>%1 behind</source> <translation>%1 detrás</translation> @@ -439,18 +411,6 @@ <translation>Transacción entrante</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Data: %1 -Cantidade: %2 -Tipo: %3 -Dirección: %4 -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>O moedeiro está <b>encriptado</b> e actualmente <b>desbloqueado</b></translation> </message> @@ -733,26 +693,6 @@ Dirección: %4 <source>command-line options</source> <translation>opcións da liña de comandos</translation> </message> - <message> - <source>UI options</source> - <translation>opcións de UI</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Fixar idioma, por exemplo "de_DE" (por defecto: locale del sistema)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Comezar minimizado</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Amosar pantalla splash no arranque (por defecto: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Escolle directorio de datos ao arrancar (por defecto: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -811,14 +751,6 @@ Dirección: %4 <translation>&Principal</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Comezar Bitcoin automáticamente despois de loguearse no sistema.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Comezar Bitcoin ao facer login no sistema</translation> - </message> - <message> <source>Reset all client options to default.</source> <translation>Restaurar todas as opcións de cliente ás por defecto</translation> </message> @@ -863,10 +795,6 @@ Dirección: %4 <translation>&Minimizar á bandexa en lugar de á barra de tarefas.</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimizar en lugar de saír da aplicación cando se pecha a xanela. Cando se habilita esta opción, a aplicación so se pechará tras seleccionar Saír no menú.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimizar ao pechar</translation> </message> @@ -879,10 +807,6 @@ Dirección: %4 <translation>&Linguaxe de interface de usuario:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>A linguaxe de interface de usuario pode fixarse aquí. Esta configuración terá efecto tras reiniciar Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Unidade na que amosar as cantidades:</translation> </message> @@ -945,11 +869,7 @@ Dirección: %4 <source>Your current total balance</source> <translation>O teu balance actual total</translation> </message> - <message> - <source>out of sync</source> - <translation>non sincronizado</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> <message> @@ -1109,18 +1029,10 @@ Dirección: %4 <translation>Arquivo de log de depuración</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Abrir o arquivo de log de depuración de Bitcoin dende o directorio actual de datos. Esto pode levar uns cantos segundos para grandes arquivos de log.</translation> - </message> - <message> <source>Clear console</source> <translation>Limpar consola</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Benvido á consola RPC de Bitcoin</translation> - </message> - <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Emprega as flechas arriba e abaixo para navegar polo historial, e <b>Ctrl-L</b> para limpar a pantalla.</translation> </message> @@ -1169,7 +1081,7 @@ Dirección: %4 </message> <message> <source>Clear all fields of the form.</source> - <translation>Limpar todos os campos do formulario</translation> + <translation>Limpar tódolos campos do formulario</translation> </message> <message> <source>Clear</source> @@ -1361,10 +1273,6 @@ Dirección: %4 <translation>Copiar cambio</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>A dirección de recepción non é válida, por favor compróbea.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>A cantidade a pagar debe ser maior que 0.</translation> </message> @@ -1377,10 +1285,6 @@ Dirección: %4 <translation>O total sobrepasa o teu balance cando se inclúe a tarifa de transacción %1.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Atopouse dirección duplicada, so se pode enviar a cada dirección unha vez por operación.</translation> - </message> - <message> <source>Warning: Invalid Bitcoin address</source> <translation>Atención: Enderezo Bitcoin non válido</translation> </message> @@ -1444,18 +1348,10 @@ Dirección: %4 <translation>Eliminar esta entrada</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Esta é unha solicitude de pago verificada</translation> - </message> - <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Introduce unha etiqueta para esta dirección para engadila á listaxe de direccións empregadas</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Esta é unha solicitude de pago non verificada</translation> - </message> - <message> <source>Pay To:</source> <translation>Pagar A:</translation> </message> @@ -1478,10 +1374,6 @@ Dirección: %4 <translation>&Asinar Mensaxe</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Podes asinar mensaxes coas túas direccións para probar que ti as posees. Ten conta de non asinar nada vago, xa que hai ataques de phishing que tentarán que asines coa túa identidade por riba deles. Asina únicamente declaracións totalmente detalladas coas que esteas de acordo.</translation> - </message> - <message> <source>Choose previously used address</source> <translation>Escoller dirección previamente empregada</translation> </message> @@ -1530,10 +1422,6 @@ Dirección: %4 <translation>&Verificar Mensaxe</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Introduce a dirección coa que asinar, a mensaxe (asegúrate de copiar exactamente os saltos de liña, espacios, tabulacións, etc.) e a sinatura debaixo para verificar a mensaxe. Ten coidado de non ler máis na sinatura do que hai no mensaxe asinado mesmo, a fin de evitar ser cazado nun ataque de home no medio.</translation> - </message> - <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>Verificar a mensaxe para asegurar que foi asinada coa dirección Bitcoin especificada</translation> </message> @@ -1765,14 +1653,6 @@ Dirección: %4 <translation>Tipo</translation> </message> <message> - <source>Address</source> - <translation>Dirección</translation> - </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>Abrir para %n bloque máis</numerusform><numerusform>Abrir para %n bloques máis</numerusform></translation> - </message> - <message> <source>Open until %1</source> <translation>Aberto ata %1</translation> </message> @@ -1789,6 +1669,10 @@ Dirección: %4 <translation>Xerado pero non aceptado</translation> </message> <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + <message> <source>Received with</source> <translation>Recibido con</translation> </message> @@ -1825,10 +1709,6 @@ Dirección: %4 <translation>Tipo de transacción.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Dirección de destino da transacción.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Cantidade borrada ou engadida no balance.</translation> </message> @@ -2111,10 +1991,6 @@ Dirección: %4 <translation>Detectada base de datos de bloques corrupta.</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Descobrir dirección IP propia (por defecto: 1 se á escoita e non -externalip)</translation> - </message> - <message> <source>Do you want to rebuild the block database now?</source> <translation>Queres reconstruír a base de datos de bloques agora?</translation> </message> @@ -2155,10 +2031,6 @@ Dirección: %4 <translation>Non hai suficientes descritores de arquivo dispoñibles.</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Reconstruír índice de cadea de bloque dende os ficheiros actuais blk000??.dat</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Especificar arquivo do moedeiro (dentro do directorio de datos)</translation> </message> @@ -2187,6 +2059,10 @@ Dirección: %4 <translation>Executar comando cando se recibe unha alerta relevante ou vemos un fork realmente longo (%s no cmd é substituído pola mensaxe)</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Escolle directorio de datos ao arrancar (por defecto: 0)</translation> + </message> + <message> <source>Information</source> <translation>Información</translation> </message> @@ -2203,6 +2079,14 @@ Dirección: %4 <translation>Enviar traza/información de depuración á consola en lugar de ao arquivo debug.log</translation> </message> <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Fixar idioma, por exemplo "de_DE" (por defecto: locale del sistema)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Amosar pantalla splash no arranque (por defecto: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Recortar o arquivo debug.log ao arrancar o cliente (por defecto: 1 cando no-debug)</translation> </message> @@ -2211,6 +2095,10 @@ Dirección: %4 <translation>Fallou a sinatura da transacción</translation> </message> <message> + <source>Start minimized</source> + <translation>Comezar minimizado</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>A cantidade da transacción é demasiado pequena</translation> </message> @@ -2235,10 +2123,6 @@ Dirección: %4 <translation>Precaución</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Precaución: Esta versión é obsoleta, precísase unha actualización!</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat corrupto, fallou o gardado</translation> </message> diff --git a/src/qt/locale/bitcoin_gu_IN.ts b/src/qt/locale/bitcoin_gu_IN.ts index b7b091aa39..ef99b0dd39 100644 --- a/src/qt/locale/bitcoin_gu_IN.ts +++ b/src/qt/locale/bitcoin_gu_IN.ts @@ -1,4 +1,4 @@ -<TS language="gu_IN" version="2.1"> +<TS language="gu_IN" version="2.0"> <context> <name>AddressBookPage</name> </context> diff --git a/src/qt/locale/bitcoin_he.ts b/src/qt/locale/bitcoin_he.ts index 45a664d6e0..9c1863de8a 100644 --- a/src/qt/locale/bitcoin_he.ts +++ b/src/qt/locale/bitcoin_he.ts @@ -1,4 +1,4 @@ -<TS language="he" version="2.1"> +<TS language="he" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -106,7 +106,7 @@ </message> <message> <source>(no label)</source> - <translation>(ללא תווית)</translation> + <translation>(אין תווית)</translation> </message> </context> <context> @@ -152,10 +152,6 @@ <translation>שינוי מילת צופן</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>נא להכניס את מילות הצופן הישנה והחדשה לארנק.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>אישור הצפנת הארנק</translation> </message> @@ -184,10 +180,6 @@ <translation>נא להזין את מילת הצופן החדשה לארנק.<br/>כדאי להשתמש במילת צופן המורכבת מ<b>עשרה תווים אקראיים ומעלה</b>, או <b>שמונה מילים ומעלה</b>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>ביטקוין ייסגר כעת כדי להשלים את תהליך ההצפנה. עליך לזכור שהצפנת הארנק שלך אינה מגנה באופן מלא על הביטקוינים שלך מתכניות זדוניות המושתלות על המחשב.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>הצפנת הארנק נכשלה</translation> </message> @@ -307,10 +299,6 @@ <translation>שליחת מטבעות לכתובת ביטקוין</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>שינוי התצורה של ביטקוין</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>גיבוי הארנק למיקום אחר</translation> </message> @@ -422,18 +410,6 @@ <source>No block source available...</source> <translation>אין מקור מקטעים זמין…</translation> </message> - <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n שעה</numerusform><numerusform>%n שעות</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n יום</numerusform><numerusform>%n ימים</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n week(s)</source> - <translation><numerusform>%n שבוע</numerusform><numerusform>%n שבועות</numerusform></translation> - </message> <message> <source>%1 and %2</source> <translation>%1 ו%2</translation> @@ -475,17 +451,6 @@ <translation>העברת קבלה</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>תאריך: %1 -כמות: %2 -סוג: %3 -כתובת: %4</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>הארנק <b>מוצפן</b> ו<b>פתוח</b> כרגע</translation> </message> @@ -513,7 +478,7 @@ Address: %4 </message> <message> <source>Amount:</source> - <translation>כמות:</translation> + <translation>סכום:</translation> </message> <message> <source>Priority:</source> @@ -521,7 +486,7 @@ Address: %4 </message> <message> <source>Fee:</source> - <translation>תשלום:</translation> + <translation>עמלה:</translation> </message> <message> <source>Dust:</source> @@ -533,7 +498,7 @@ Address: %4 </message> <message> <source>Change:</source> - <translation>שינוי:</translation> + <translation>עודף:</translation> </message> <message> <source>(un)select all</source> @@ -597,7 +562,7 @@ Address: %4 </message> <message> <source>Copy fee</source> - <translation>העתקת מחיר</translation> + <translation>העתקת עמלה</translation> </message> <message> <source>Copy after fee</source> @@ -672,10 +637,6 @@ Address: %4 <translation>לא</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>תווית זו מאדימה אם גודל ההעברה עולה על 1000 בתים.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>זאת אומרת שנחוצה עמלה של לא פחות מ־%1 לכל קילו בית.</translation> </message> @@ -688,10 +649,6 @@ Address: %4 <translation>העברות עם עדיפות גבוהה, יותר סיכוי שיכנסו לתוך המקטע.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>תווית זו מאדימה אם העדיפות היא פחות מ„בינוני“</translation> - </message> - <message> <source>(no label)</source> <translation>(אין תווית)</translation> </message> @@ -812,30 +769,6 @@ Address: %4 <source>command-line options</source> <translation>אפשרויות שורת פקודה</translation> </message> - <message> - <source>UI options</source> - <translation>אפשרויות מנשק</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>הגדרת שפה, למשל „he_il“ (בררת מחדל: שפת המערכת)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>התחלה במצב ממוזער</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>הגדרות אישורי בסיס של SSL לבקשות תשלום (בררת המחדל: -מערכת-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>הצגת מסך פתיחה בעת הפעלה (בררת מחדל: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>בחירת תיקיית נתונים עם ההפעלה (בררת מחדל: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -910,14 +843,6 @@ Address: %4 <translation>&ראשי</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>הפעלת ביטקוין אוטומטית לאחר כניסה למערכת.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>ה&פעלת ביטקוין בעת הכניסה למערכת</translation> - </message> - <message> <source>Size of &database cache</source> <translation>גודל מ&טמון מסד הנתונים</translation> </message> @@ -1022,10 +947,6 @@ Address: %4 <translation>מ&זעור למגש במקום לשורת המשימות</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>מזעור התכנית במקום לצאת ממנה כשהחלון נסגר. כשאפשרות זו פעילה, התכנית תיסגר רק לאחר בחירת יציאה מהתפריט.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>מ&זעור עם סגירה</translation> </message> @@ -1038,10 +959,6 @@ Address: %4 <translation>&שפת מנשק המשתמש:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>להלן ניתן לקבוע את שפת מנשק המשתמש. הגדרה זו תיכנס לתוקף לאחר הפעלה מחדש של ביטקוין.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>י&חידת מידה להצגת כמויות:</translation> </message> @@ -1078,10 +995,6 @@ Address: %4 <translation>נדרשת הפעלה מחדש של הלקוח כדי להפעיל את השינויים.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>הלקוח יכבה, האם להמשיך?</translation> - </message> - <message> <source>This change would require a client restart.</source> <translation>שינוי זה ידרוש הפעלה מחדש של תכנית הלקוח.</translation> </message> @@ -1160,10 +1073,6 @@ Address: %4 <source>Current total balance in watch-only addresses</source> <translation>המאזן הכולל הנוכחי בכתובות לצפייה בלבד</translation> </message> - <message> - <source>out of sync</source> - <translation>לא בסנכרון</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1184,10 +1093,6 @@ Address: %4 <translation>רשת בקשת התשלום אינה תואמת לרשת הלקוח.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>בקשת התשלום פגה.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>בקשת התשלום לא החלה.</translation> </message> @@ -1255,10 +1160,6 @@ Address: %4 <translation>סוכן משתמש</translation> </message> <message> - <source>Address/Hostname</source> - <translation>כתובת/שם מארח</translation> - </message> - <message> <source>Ping Time</source> <translation>זמן המענה</translation> </message> @@ -1290,14 +1191,6 @@ Address: %4 <translation>%1 שניות</translation> </message> <message> - <source>NETWORK</source> - <translation>רשת</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>לא ידוע</translation> - </message> - <message> <source>None</source> <translation>ללא</translation> </message> @@ -1496,18 +1389,10 @@ Address: %4 <translation>קובץ יומן ניפוי</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>פתיחת קובץ יומן הניפוי מתיקיית הנתונים הנוכחית. פעולה זו עשויה להימשך מספר שניות עבור קובצי יומן גדולים.</translation> - </message> - <message> <source>Clear console</source> <translation>ניקוי מסוף הבקרה</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>ברוכים הבאים למסוף ה־RPC של ביטקוין.</translation> - </message> - <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>יש להשתמש בחצים למעלה ולמטה כדי לנווט בהיסטוריה, וב־<b>Ctrl-L</b> כדי לנקות את המסך.</translation> </message> @@ -1596,7 +1481,7 @@ Address: %4 </message> <message> <source>Clear all fields of the form.</source> - <translation>ניקוי כל השדות של הטופס.</translation> + <translation>ניקוי של כל השדות בטופס.</translation> </message> <message> <source>Clear</source> @@ -1801,7 +1686,7 @@ Address: %4 </message> <message> <source>Clear &All</source> - <translation>ניקוי ה&כול</translation> + <translation>&ניקוי הכול</translation> </message> <message> <source>Balance:</source> @@ -1829,7 +1714,7 @@ Address: %4 </message> <message> <source>Copy amount</source> - <translation>העתקת סכום</translation> + <translation>העתקת כמות</translation> </message> <message> <source>Copy fee</source> @@ -1860,10 +1745,6 @@ Address: %4 <translation>או</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>כתובת המוטב אינה תקינה, נא לבדוק שוב.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>הכמות לתשלום חייבת להיות גדולה מ־0.</translation> </message> @@ -1876,10 +1757,6 @@ Address: %4 <translation>הכמות הכוללת, ובכללה עמלת העברה בסך %1, עולה על המאזן שלך.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>כתובת כפולה נמצאה, ניתן לשלוח לכל כתובת רק פעם אחת בכל פעולת שליחה.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>יצירת ההעברה נכשלה!</translation> </message> @@ -1963,10 +1840,6 @@ Address: %4 <translation>הודעה:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>זוהי בקשה מאומתת לתשלום.</translation> - </message> - <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>יש להזין תווית עבור כתובת זו כדי להוסיף אותה לרשימת הכתובות בשימוש</translation> </message> @@ -1975,10 +1848,6 @@ Address: %4 <translation>הודעה שצורפה לביטקוין: כתובת שתאוחסן בהעברה לצורך מעקב מצדך. לתשומת לבך: הודעה זו לא תישלח ברשת הביטקוין.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>זוהי בקשת תשלום בלתי־מאומתת.</translation> - </message> - <message> <source>Pay To:</source> <translation>תשלום לטובת:</translation> </message> @@ -2009,10 +1878,6 @@ Address: %4 <translation>חתימה על הו&דעה</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>ניתן לחתום על הודעות עם הכתובות שלך כדי להוכיח שהן בבעלותך. מומלץ להיזהר לא לחתום על משהו מפוקפק, שכן התקפות דיוג עשויות לגרום לך בעורמה למסור את זהותך. רצוי לחתום רק על הצהרות מפורטות לחלוטין שהסכמת עמן.</translation> - </message> - <message> <source>The Bitcoin address to sign the message with</source> <translation>כתובת הביטקוין אתה לחתום אתה את ההודעה</translation> </message> @@ -2065,10 +1930,6 @@ Address: %4 <translation>&אימות הודעה</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>הכנס למטה את הכתובת החותמת, ההודעה (ודא שאתה מעתיק מעברי שורה, רווחים, טאבים וכו' באופן מדויק) והחתימה כדי לאמת את ההודעה. היזהר לא לפרש את החתימה כיותר ממה שמופיע בהודעה החתומה בעצמה, כדי להימנע מליפול קורבן למתקפת איש-באמצע.</translation> - </message> - <message> <source>The Bitcoin address the message was signed with</source> <translation>כתובת הביטקוין שאתה נחתמה ההודעה</translation> </message> @@ -2293,10 +2154,6 @@ Address: %4 <source>, has not been successfully broadcast yet</source> <translation>, טרם שודר בהצלחה</translation> </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>פתיחה למשך מקטע %n נוסף</numerusform><numerusform>פתיחה למשך %n מקטעים נוספים</numerusform></translation> - </message> <message> <source>unknown</source> <translation>לא ידוע</translation> @@ -2324,17 +2181,9 @@ Address: %4 <translation>סוג</translation> </message> <message> - <source>Address</source> - <translation>כתובת</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>לא בשל (%1 אישורים, יהיו זמינים לאחר %2)</translation> </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>פתח למשך בלוק %n יותר</numerusform><numerusform>פתיחה למשך %n מקטעים נוספים</numerusform></translation> - </message> <message> <source>Open until %1</source> <translation>פתוחה עד %1</translation> @@ -2356,6 +2205,10 @@ Address: %4 <translation>מנותק</translation> </message> <message> + <source>Label</source> + <translation>תווית</translation> + </message> + <message> <source>Unconfirmed</source> <translation>ללא אישור</translation> </message> @@ -2412,10 +2265,6 @@ Address: %4 <translation>האם כתובות לצפייה בלבד מעורבות בהעברה זאת או שלא.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>כתובת היעד של ההעברה.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>הכמות שהתווספה או הוסרה מהיתרה.</translation> </message> @@ -2662,10 +2511,6 @@ Address: %4 <translation>מחיקת כל העברות הארנק ולשחזר רק את החלקים המסוימים בשרשרת המקטעים באמצעות -rescan עם ההפעלה</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>כניסה למצב בדיקת נסיגה, שמשתמש בשרשרת מיוחדת בה ניתן לפתור את המקטעים במהירות.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>ביצוע פקודה כאשר העברה בארנק משתנה (%s ב־cmd יוחלף ב־TxID)</translation> </message> @@ -2730,10 +2575,6 @@ Address: %4 <translation>אפשרויות ניפוי/בדיקה:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>לגלות את כתובת ה־IP העצמית (בררת מחדל: 1 בעת האזנה וללא -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>לא לטעון את הארנק ולנטרל קריאות RPC</translation> </message> @@ -2790,10 +2631,6 @@ Address: %4 <translation>תמיד להתחבר למפרקים ברשת <net> (ipv4, ipv6 או onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>בנייה מחדש של מפתח שרשרת המקטעים מקובצי ה־blk000??.dat הנוכחיים.</translation> - </message> - <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>הגדרת גודל מטמון מסדי הנתונים במגה בתים (%d עד %d, בררת מחדל: %d)</translation> </message> @@ -2806,10 +2643,6 @@ Address: %4 <translation>ציון קובץ ארנק (בתוך תיקיית הנתונים)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>תכונה זו מיועדת לכלי בדיקות נסיגה ופיתוח יישומים.</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>המקטעים מאומתים…</translation> </message> @@ -2838,10 +2671,6 @@ Address: %4 <translation>הרץ פקודה כאשר ההתראה הרלוונטית מתקבלת או כשאנחנו עדים לפיצול ארוך מאוד (%s בשורת הפקודה יוחלף ע"י ההודעה)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>העמלות (ב־BTC/ק״ב) הנמוכות מהסכום הזה נחשבות לעמלות אפס ליצירת העברה (בררת מחדל: %s)</translation> - </message> - <message> <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> <translation>אזהרה: נא לבדוק שהתאריך והשעה של המחשב שלך נכונים! אם השעון שלך שגוי ליבת ביטקוין לא תעבוד כראוי.</translation> </message> @@ -2850,6 +2679,10 @@ Address: %4 <translation>לא ניתן לפתור את הכתובת -whitebind: '%s'</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>בחירת תיקיית נתונים עם ההפעלה (בררת מחדל: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>התחברות דרך מתווך SOCKS5</translation> </message> @@ -2914,18 +2747,26 @@ Address: %4 <translation>הגדרות שרת RPC</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>להשמיט אקראית אחת מתוך כל <n> הודעות רשת</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>שלח מידע דיבאג ועקבה לקונסולה במקום לקובץ debug.log</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>הגדרות אישורי בסיס של SSL לבקשות תשלום (בררת המחדל: -מערכת-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>הגדרת שפה, למשל „he_il“ (בררת מחדל: שפת המערכת)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>הצגת כל אפשרויות הניפוי (שימוש: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>הצגת מסך פתיחה בעת הפעלה (בררת מחדל: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>כיווץ הקובץ debug.log בהפעלת הלקוח (בררת מחדל: 1 ללא -debug)</translation> </message> @@ -2934,6 +2775,10 @@ Address: %4 <translation>החתימה על ההעברה נכשלה</translation> </message> <message> + <source>Start minimized</source> + <translation>התחלה במצב ממוזער</translation> + </message> + <message> <source>This is experimental software.</source> <translation>זוהי תכנית נסיונית.</translation> </message> @@ -2970,10 +2815,6 @@ Address: %4 <translation>אזהרה</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>אזהרה: הגרסה הזאת מיושנת, יש צורך בשדרוג!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>אזהרה: הארגומנט שאינו נתמך עוד -benchmark לא הופעל, נא להשתמש ב־-debug=bench.</translation> </message> diff --git a/src/qt/locale/bitcoin_hi_IN.ts b/src/qt/locale/bitcoin_hi_IN.ts index 208d1e0369..01e074ffc6 100644 --- a/src/qt/locale/bitcoin_hi_IN.ts +++ b/src/qt/locale/bitcoin_hi_IN.ts @@ -1,4 +1,4 @@ -<TS language="hi_IN" version="2.1"> +<TS language="hi_IN" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -84,10 +84,6 @@ <translation>पहचान शब्द/अक्षर बदलिये !</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>कृपा करके पुराना एवं नया पहचान शब्द/अक्षर वॉलेट में डालिए !</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>वॉलेट एनक्रिपशन को प्रमाणित कीजिए !</translation> </message> @@ -187,22 +183,6 @@ <source>Tabs toolbar</source> <translation>टैबस टूलबार</translation> </message> - <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n सक्रिया संपर्क बीटकोइन नेटवर्क से</numerusform><numerusform>%n सक्रिया संपर्क बीटकोइन नेटवर्क से</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n घंटा</numerusform><numerusform>%n घंटे</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n दिन</numerusform><numerusform>%n दिनो</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n week(s)</source> - <translation><numerusform>%n हफ़्ता</numerusform><numerusform>%n हफ्ते</numerusform></translation> - </message> <message> <source>%1 behind</source> <translation>%1 पीछे</translation> @@ -232,17 +212,6 @@ <translation>प्राप्त हुई ट्रांजक्शन</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>तारीख: %1\n -राशि: %2\n -टाइप: %3\n -पता:%4\n</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>वॉलेट एन्क्रिप्टेड है तथा अभी लॉक्ड नहीं है</translation> </message> @@ -627,10 +596,6 @@ Address: %4 <translation>टाइप</translation> </message> <message> - <source>Address</source> - <translation>पता</translation> - </message> - <message> <source>Open until %1</source> <translation>खुला है जबतक %1</translation> </message> @@ -647,8 +612,12 @@ Address: %4 <translation>जेनरेट किया गया किंतु स्वीकारा नही गया !</translation> </message> <message> + <source>Label</source> + <translation>लेबल</translation> + </message> + <message> <source>Received with</source> - <translation>स्वीकारा गया</translation> + <translation>स्वीकार करना</translation> </message> <message> <source>Received from</source> @@ -683,10 +652,6 @@ Address: %4 <translation>ट्रांसेक्शन का प्रकार|</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>ट्रांसेक्शन की मंजिल का पता|</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>अमाउंट बैलेंस से निकला या जमा किया गया |</translation> </message> diff --git a/src/qt/locale/bitcoin_hr.ts b/src/qt/locale/bitcoin_hr.ts index c4dc0ded97..74d380ec2b 100644 --- a/src/qt/locale/bitcoin_hr.ts +++ b/src/qt/locale/bitcoin_hr.ts @@ -1,7 +1,11 @@ -<TS language="hr" version="2.1"> +<TS language="hr" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Desni klik za uređivanje adresa i oznaka</translation> + </message> + <message> <source>Create a new address</source> <translation>Dodajte novu adresu</translation> </message> @@ -23,7 +27,7 @@ </message> <message> <source>&Copy Address</source> - <translation>&Kopirati adresu</translation> + <translation>&Kopiraj adresu</translation> </message> <message> <source>Delete the currently selected address from the list</source> @@ -31,15 +35,15 @@ </message> <message> <source>Export the data in the current tab to a file</source> - <translation>Izvoz podataka iz trenutnog taba u datoteku</translation> + <translation>Izvoz podataka iz trenutnog lista u datoteku</translation> </message> <message> <source>&Export</source> - <translation>&Izvoz</translation> + <translation>&Izvozi</translation> </message> <message> <source>&Delete</source> - <translation>&Brisanje</translation> + <translation>Iz&briši</translation> </message> <message> <source>Choose the address to send coins to</source> @@ -63,19 +67,19 @@ </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>Ovo su vaše Bitcoin adrese za slanje uplate. Uvijek provjerite iznos i adresu primatelja prije slanja novca.</translation> + <translation>Ovo su vaše Bitcoin adrese za slanje novca. Uvijek provjerite iznos i adresu primatelja prije slanja novca.</translation> </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> - <translation>Ovo su vaše Bitcoin adrese za primanje isplate. Preporučamo da koristite novu primateljsku adresu za svaku transakciju.</translation> + <translation>Ovo su vaše Bitcoin adrese za primanje novca. Preporučamo da koristite novu adresu za primanje za svaku transakciju.</translation> </message> <message> <source>Copy &Label</source> - <translation>Kopirati &oznaku</translation> + <translation>Kopiraj &oznaku</translation> </message> <message> <source>&Edit</source> - <translation>&Izmjeniti</translation> + <translation>&Uredi</translation> </message> <message> <source>Export Address List</source> @@ -83,7 +87,7 @@ </message> <message> <source>Comma separated file (*.csv)</source> - <translation>Datoteka vrijednosti odvojenih zarezom (*. csv)</translation> + <translation>Datoteka podataka odvojenih zarezima (*.csv)</translation> </message> <message> <source>Exporting Failed</source> @@ -152,16 +156,12 @@ <translation>Promjena lozinke</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Unesite staru i novu lozinku za novčanik.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Potvrdi šifriranje novčanika</translation> </message> <message> <source>Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!</source> - <translation>Upozorenje: Ako šifrirate vaš novčanik i izgubite lozinku, <b>IZGUBIT ĆETE SVE SVOJE BITCOINSE!</b></translation> + <translation>Upozorenje: Ako šifrirate vaš novčanik i izgubite lozinku, <b>IZGUBIT ĆETE SVE SVOJE BITCOINE!</b></translation> </message> <message> <source>Are you sure you wish to encrypt your wallet?</source> @@ -184,8 +184,8 @@ <translation>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></translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin će se sada zatvoriti kako bi dovršio postupak šifriranja. Zapamtite da šifriranje vašeg novčanika ne može u potpunosti zaštititi vaše bitcoine od krađe preko zloćudnog softvera koji bi bio na vašem računalu.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Unesite staru i novu lozinku za novčanik.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -264,7 +264,7 @@ </message> <message> <source>&Options...</source> - <translation>Pos&tavke</translation> + <translation>Pos&tavke...</translation> </message> <message> <source>&Encrypt Wallet...</source> @@ -272,19 +272,19 @@ </message> <message> <source>&Backup Wallet...</source> - <translation>Si&gurnosno kopiraj novčanik...</translation> + <translation>Spremi &kopiju novčanika...</translation> </message> <message> <source>&Change Passphrase...</source> - <translation>&Promjena lozinke...</translation> + <translation>Promjena &lozinke...</translation> </message> <message> <source>&Sending addresses...</source> - <translation>Adrese za s&lanje</translation> + <translation>Adrese za &slanje</translation> </message> <message> <source>&Receiving addresses...</source> - <translation>Adrese za p&rimanje</translation> + <translation>Adrese za &primanje</translation> </message> <message> <source>Open &URI...</source> @@ -307,10 +307,6 @@ <translation>Slanje novca na bitcoin adresu</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Promijeni postavke konfiguracije za bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Napravite sigurnosnu kopiju novčanika na drugoj lokaciji</translation> </message> @@ -320,11 +316,11 @@ </message> <message> <source>&Debug window</source> - <translation>&Ispravljanje programerskih pogrešaka</translation> + <translation>Konzola za dijagnostiku</translation> </message> <message> <source>Open debugging and diagnostic console</source> - <translation>Otvori konzolu za dijagnostiku i otklanjanje programskih pogrešaka.</translation> + <translation>Otvori konzolu za dijagnostiku</translation> </message> <message> <source>&Verify message...</source> @@ -344,11 +340,11 @@ </message> <message> <source>&Receive</source> - <translation>Pri&miti</translation> + <translation>Pri&mi</translation> </message> <message> <source>Show information about Bitcoin Core</source> - <translation>Prikaži informacije o Bitcoin Coreu</translation> + <translation>Prikaži informacije o programu Bitcoin Core</translation> </message> <message> <source>&Show / Hide</source> @@ -360,15 +356,15 @@ </message> <message> <source>Encrypt the private keys that belong to your wallet</source> - <translation>Šifriraj privatne ključeve koji pripadaju tvom novčaniku</translation> + <translation>Šifriranje privatnih ključeva koji u novčaniku</translation> </message> <message> <source>Sign messages with your Bitcoin addresses to prove you own them</source> - <translation>Potpiši poruke svojim Bitcoin adresama kako bi dokazao da si njihov vlasnik</translation> + <translation>Poruku potpišemo s bitcoin adresom, kako bi dokazali vlasništvo nad tom adresom</translation> </message> <message> <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source> - <translation>Provjerite porkue kako bi se uvjerili da su potpisane navedenim Bitcoin adresama</translation> + <translation>Provjeravanje poruke, kao dokaz, da je potpisana navedenom bitcoin adresom</translation> </message> <message> <source>&File</source> @@ -388,27 +384,75 @@ </message> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Jezgra</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>Request payments (generates QR codes and bitcoin: URIs)</source> - <translation>Zatraži uplate (Stvara QR kodove i bitcoin: URIje)</translation> + <translation>Zatraži uplatu (stvara QR kod i bitcoin: URI adresu)</translation> </message> <message> <source>&About Bitcoin Core</source> - <translation>&O Bitcoin Jezgri</translation> + <translation>&O programu Bitcoin Core</translation> + </message> + <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Promijeni postavke programa</translation> </message> <message> <source>Show the list of used sending addresses and labels</source> - <translation>Prikaži popis korištenih adresa i oznaka za slanje isplate</translation> + <translation>Prikaži popis korištenih adresa i oznaka za slanje novca</translation> </message> <message> <source>Show the list of used receiving addresses and labels</source> - <translation>Prikaži popis korištenih adresa i oznaka za primanje isplate</translation> + <translation>Prikaži popis korištenih adresa i oznaka za primanje novca</translation> + </message> + <message> + <source>Open a bitcoin: URI or payment request</source> + <translation>Otvori bitcoin: URI adresu ili zahtjev za uplatu</translation> + </message> + <message> + <source>&Command-line options</source> + <translation>Opcije &naredbene linije</translation> + </message> + <message> + <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> + <translation>Ispis svih opcija naredbene linije programa sa kratkim opisom</translation> </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n aktivna veza na Bitcoin mrežu</numerusform><numerusform>%n aktivne veze na Bitcoin mrežu</numerusform><numerusform>%n aktivnih veza na Bitcoin mrežu</numerusform></translation> + <translation><numerusform>%n aktivna veza na Bitcoin mrežu</numerusform><numerusform>%n aktivnih veza na Bitcoin mrežu</numerusform><numerusform>%n aktivnih veza na Bitcoin mrežu</numerusform></translation> + </message> + <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Obrađen %n blok povijesti transakcije.</numerusform><numerusform>Obrađeno %n bloka povijesti transakcije.</numerusform><numerusform>Obrađeno %n blokova povijesti transakcije.</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n sat</numerusform><numerusform>%n sata</numerusform><numerusform>%n sati</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n dan</numerusform><numerusform>%n dana</numerusform><numerusform>%n dana</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n tjedan</numerusform><numerusform>%n tjedna</numerusform><numerusform>%n tjedana</numerusform></translation> + </message> + <message> + <source>%1 and %2</source> + <translation>%1 i %2</translation> + </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n godina</numerusform><numerusform>%n godine</numerusform><numerusform>%n godina</numerusform></translation> + </message> + <message> + <source>Last received block was generated %1 ago.</source> + <translation>Zadnji primljeni blok je bio ustvaren prije %1.</translation> + </message> + <message> + <source>Transactions after this will not yet be visible.</source> + <translation>Transakcije izvršene za tim blokom nisu još prikazane.</translation> </message> <message> <source>Error</source> @@ -431,26 +475,44 @@ <translation>Ažuriranje...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Poslana transakcija</translation> + <source>Date: %1 +</source> + <translation>Datum: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Dolazna transakcija</translation> + <source>Amount: %1 +</source> + <translation>Iznos: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 +</source> + <translation>Vrsta: %1 +</translation> + </message> + <message> + <source>Label: %1 </source> - <translation>Datum:%1 -Iznos:%2 -Tip:%3 -Adresa:%4 + <translation>Oznaka: %1 </translation> </message> <message> + <source>Address: %1 +</source> + <translation>Adresa: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Poslana transakcija</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Dolazna transakcija</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Novčanik je <b>šifriran</b> i trenutno <b>otključan</b></translation> </message> @@ -465,34 +527,146 @@ Adresa:%4 <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>Izbor ulaza transakcije</translation> + </message> + <message> + <source>Quantity:</source> + <translation>Količina:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>Bajtova:</translation> + </message> + <message> <source>Amount:</source> <translation>Iznos:</translation> </message> <message> + <source>Priority:</source> + <translation>Prioriteta:</translation> + </message> + <message> + <source>Fee:</source> + <translation>Naknada:</translation> + </message> + <message> + <source>Dust:</source> + <translation>Prah:</translation> + </message> + <message> + <source>Change:</source> + <translation>Vraćeno:</translation> + </message> + <message> + <source>(un)select all</source> + <translation>Izaberi sve/ništa</translation> + </message> + <message> <source>Amount</source> <translation>Iznos</translation> </message> <message> + <source>Received with label</source> + <translation>Primljeno pod oznakom</translation> + </message> + <message> + <source>Received with address</source> + <translation>Primljeno na adresu</translation> + </message> + <message> <source>Date</source> <translation>Datum</translation> </message> <message> + <source>Confirmations</source> + <translation>Broj potvrda</translation> + </message> + <message> <source>Confirmed</source> <translation>Potvrđeno</translation> </message> <message> + <source>Priority</source> + <translation>Prioriteta</translation> + </message> + <message> <source>Copy address</source> - <translation>Kopirati adresu</translation> + <translation>Kopiraj adresu</translation> </message> <message> <source>Copy label</source> - <translation>Kopirati oznaku</translation> + <translation>Kopiraj oznaku</translation> </message> <message> <source>Copy amount</source> <translation>Kopiraj iznos</translation> </message> <message> + <source>Copy transaction ID</source> + <translation>Kopiraj ID transakcije</translation> + </message> + <message> + <source>highest</source> + <translation>najviša</translation> + </message> + <message> + <source>higher</source> + <translation>viša</translation> + </message> + <message> + <source>high</source> + <translation>visoka</translation> + </message> + <message> + <source>medium-high</source> + <translation>srednje visoka</translation> + </message> + <message> + <source>medium</source> + <translation>srednja</translation> + </message> + <message> + <source>low-medium</source> + <translation>srednje niska</translation> + </message> + <message> + <source>low</source> + <translation>niska</translation> + </message> + <message> + <source>lower</source> + <translation>niža</translation> + </message> + <message> + <source>lowest</source> + <translation>najniža</translation> + </message> + <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Oznaka postane crvene boje ako je transakcija veća od 1000 bajtova.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Oznaka postane crvene boje ako je prioriteta transakcije niža od "srednja"</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Oznaka postane crvene boje ako je iznos manji od %1</translation> + </message> + <message> + <source>yes</source> + <translation>da</translation> + </message> + <message> + <source>no</source> + <translation>ne</translation> + </message> + <message> + <source>Transactions with higher priority are more likely to get included into a block.</source> + <translation>Transakcije više prioritete imaju veću vjerojatnost da budu prije dodane u novi blok.</translation> + </message> + <message> <source>(no label)</source> <translation>(bez oznake)</translation> </message> @@ -501,13 +675,21 @@ Adresa:%4 <name>EditAddressDialog</name> <message> <source>Edit Address</source> - <translation>Izmjeni adresu</translation> + <translation>Uredi adresu</translation> </message> <message> <source>&Label</source> <translation>&Oznaka</translation> </message> <message> + <source>The label associated with this address list entry</source> + <translation>Oznaka bitcoin adrese</translation> + </message> + <message> + <source>The address associated with this address list entry. This can only be modified for sending addresses.</source> + <translation>Bitcoin adresa. Izmjene adrese su moguće samo za adrese za slanje.</translation> + </message> + <message> <source>&Address</source> <translation>&Adresa</translation> </message> @@ -547,37 +729,49 @@ Adresa:%4 <context> <name>FreespaceChecker</name> <message> + <source>A new data directory will be created.</source> + <translation>Stvoren će biti novi direktorij za podatke.</translation> + </message> + <message> <source>name</source> <translation>ime</translation> </message> - </context> + <message> + <source>Cannot create data directory here.</source> + <translation>Nije moguće stvoriti direktorij za podatke na tom mjestu.</translation> + </message> +</context> <context> <name>HelpMessageDialog</name> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Jezgra</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>version</source> <translation>verzija</translation> </message> <message> + <source>(%1-bit)</source> + <translation>(%1-bit)</translation> + </message> + <message> <source>About Bitcoin Core</source> - <translation>O Bitcoin Jezrgu</translation> + <translation>O programu Bitcoin Core</translation> </message> <message> - <source>Usage:</source> - <translation>Upotreba:</translation> + <source>Command-line options</source> + <translation>Opcije programa u naredbenoj liniji</translation> </message> <message> - <source>UI options</source> - <translation>UI postavke</translation> + <source>Usage:</source> + <translation>Upotreba:</translation> </message> <message> - <source>Start minimized</source> - <translation>Pokreni minimiziran</translation> + <source>command-line options</source> + <translation>opcije programa u naredbenoj liniji</translation> </message> - </context> +</context> <context> <name>Intro</name> <message> @@ -585,17 +779,41 @@ Adresa:%4 <translation>Dobrodošli</translation> </message> <message> + <source>Welcome to Bitcoin Core.</source> + <translation>Dobrodošli u programu Bitcoin Core.</translation> + </message> + <message> <source>Bitcoin Core</source> - <translation>Bitcoin Jezgra</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>Error</source> - <translation>Pogreška</translation> + <translation>Greška</translation> </message> </context> <context> <name>OpenURIDialog</name> - </context> + <message> + <source>Open URI</source> + <translation>Otvori URI adresu</translation> + </message> + <message> + <source>Open payment request from URI or file</source> + <translation>Otvori zahtjev za plaćanje iz URI adrese ili datoteke</translation> + </message> + <message> + <source>URI:</source> + <translation>URI:</translation> + </message> + <message> + <source>Select payment request file</source> + <translation>Izaberi datoteku zahtjeva za plaćanje</translation> + </message> + <message> + <source>Select payment request file to open</source> + <translation>Izaberi datoteku zahtjeva za plaćanje</translation> + </message> +</context> <context> <name>OptionsDialog</name> <message> @@ -607,18 +825,58 @@ Adresa:%4 <translation>&Glavno</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Automatski pokreni Bitcoin kad se uključi računalo</translation> + <source>Size of &database cache</source> + <translation>Veličina predmemorije baze podataka</translation> + </message> + <message> + <source>MB</source> + <translation>MB</translation> + </message> + <message> + <source>Number of script &verification threads</source> + <translation>Broj CPU niti za verifikaciju transakcija</translation> + </message> + <message> + <source>Allow incoming connections</source> + <translation>Dozvoli povezivanje izvana</translation> + </message> + <message> + <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> + <translation>IP adresa proxy servera (npr. IPv4: 127.0.0.1 / IPv6: ::1)</translation> + </message> + <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Minimizirati aplikaciju umjesto zatvoriti, kada se zatvori prozor. Kada je ova opcija omogućena, aplikacija će biti zatvorena tek nakon odabira naredbe Izlaz u izborniku.</translation> + </message> + <message> + <source>Reset all client options to default.</source> + <translation>Nastavi sve postavke programa na početne vrijednosti.</translation> </message> <message> - <source>&Start Bitcoin on system login</source> - <translation>&Pokreni Bitcoin kod pokretanja sustava</translation> + <source>&Reset Options</source> + <translation>Po&nastavi postavke</translation> </message> <message> <source>&Network</source> <translation>&Mreža</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Program se automatski pokrene po prijavi u sustav.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Pokreni program kod prijave u sustav</translation> + </message> + <message> + <source>W&allet</source> + <translation>&Novčanik</translation> + </message> + <message> + <source>&Spend unconfirmed change</source> + <translation>&Trošenje nepotvrđenih vraćenih iznosa</translation> + </message> + <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> <translation>Automatski otvori port Bitcoin klijenta na ruteru. To radi samo ako ruter podržava UPnP i ako je omogućen.</translation> </message> @@ -631,8 +889,12 @@ Adresa:%4 <translation>Proxy &IP:</translation> </message> <message> + <source>&Port:</source> + <translation>&Vrata:</translation> + </message> + <message> <source>Port of the proxy (e.g. 9050)</source> - <translation>Port od proxy-a (npr. 9050)</translation> + <translation>Proxy vrata (npr. 9050)</translation> </message> <message> <source>&Window</source> @@ -647,10 +909,6 @@ Adresa:%4 <translation>&Minimiziraj u sistemsku traku umjesto u traku programa</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimizirati umjesto izaći iz aplikacije kada je prozor zatvoren. Kada je ova opcija omogućena, aplikacija će biti zatvorena tek nakon odabira Izlaz u izborniku.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimiziraj kod zatvaranja</translation> </message> @@ -659,8 +917,12 @@ Adresa:%4 <translation>&Prikaz</translation> </message> <message> + <source>User Interface &language:</source> + <translation>Jezi&k sučelja:</translation> + </message> + <message> <source>&Unit to show amounts in:</source> - <translation>&Jedinica za prikazivanje iznosa:</translation> + <translation>&Jedinica za prikaz iznosa:</translation> </message> <message> <source>Choose the default subdivision unit to show in the interface and when sending coins.</source> @@ -722,6 +984,10 @@ Adresa:%4 <context> <name>QRImageWidget</name> <message> + <source>&Save Image...</source> + <translation>&Spremi sliku...</translation> + </message> + <message> <source>Save QR Code</source> <translation>Spremi QR kod</translation> </message> @@ -742,11 +1008,11 @@ Adresa:%4 </message> <message> <source>&Information</source> - <translation>&Informacija</translation> + <translation>&Informacije</translation> </message> <message> <source>Using OpenSSL version</source> - <translation>Koristim OpenSSL verziju</translation> + <translation>OpenSSL verzija u upotrebi</translation> </message> <message> <source>Network</source> @@ -758,7 +1024,7 @@ Adresa:%4 </message> <message> <source>Number of connections</source> - <translation>Broj konekcija</translation> + <translation>Broj veza</translation> </message> <message> <source>Block chain</source> @@ -769,6 +1035,34 @@ Adresa:%4 <translation>Trenutni broj blokova</translation> </message> <message> + <source>Received</source> + <translation>Primljeno</translation> + </message> + <message> + <source>Sent</source> + <translation>Poslano</translation> + </message> + <message> + <source>Direction</source> + <translation>Smjer</translation> + </message> + <message> + <source>Version</source> + <translation>Verzija</translation> + </message> + <message> + <source>Connection Time</source> + <translation>Trajanje veze</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Bajtova poslano</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Bajtova primljeno</translation> + </message> + <message> <source>Last block time</source> <translation>Posljednje vrijeme bloka</translation> </message> @@ -781,6 +1075,10 @@ Adresa:%4 <translation>&Konzola</translation> </message> <message> + <source>&Network Traffic</source> + <translation>&Mrežni promet</translation> + </message> + <message> <source>Totals</source> <translation>Ukupno:</translation> </message> @@ -789,27 +1087,47 @@ Adresa:%4 <translation>Očisti konzolu</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> + <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Dobrodošli u Bitcoin RPC konzolu.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> - <translation>Kako bi navigirali kroz povijest koristite strelice gore i dolje. <b>Ctrl-L</b> kako bi očistili ekran.</translation> + <translation>Koristite tipke gore i dolje za izbor već korištenih naredbi. <b>Ctrl-L</b> kako bi očistili ekran i povijest naredbi.</translation> + </message> + <message> + <source>Unknown</source> + <translation>Nepoznato</translation> </message> </context> <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>&Iznos:</translation> + </message> + <message> <source>&Label:</source> <translation>&Oznaka:</translation> </message> <message> + <source>&Message:</source> + <translation>&Poruka:</translation> + </message> + <message> + <source>Clear all fields of the form.</source> + <translation>Obriši sva polja</translation> + </message> + <message> + <source>&Request payment</source> + <translation>&Zatraži plaćanje</translation> + </message> + <message> <source>Show</source> <translation>Pokaži</translation> </message> <message> <source>Copy label</source> - <translation>Kopirati oznaku</translation> + <translation>Kopiraj oznaku</translation> </message> <message> <source>Copy amount</source> @@ -823,6 +1141,22 @@ Adresa:%4 <translation>QR kôd</translation> </message> <message> + <source>Copy &URI</source> + <translation>Kopiraj &URI</translation> + </message> + <message> + <source>Copy &Address</source> + <translation>Kopiraj &adresu</translation> + </message> + <message> + <source>&Save Image...</source> + <translation>&Spremi sliku...</translation> + </message> + <message> + <source>URI</source> + <translation>URI</translation> + </message> + <message> <source>Address</source> <translation>Adresa</translation> </message> @@ -840,9 +1174,13 @@ Adresa:%4 </message> <message> <source>Resulting URI too long, try to reduce the text for label / message.</source> - <translation>Rezultirajući URI je predug, probajte umanjiti tekst za naslov / poruku.</translation> + <translation>URI je predug, probajte skratiti tekst za naslov / poruku.</translation> </message> - </context> + <message> + <source>Error encoding URI into QR Code.</source> + <translation>Greška kod kodiranja URI adrese u QR kod.</translation> + </message> +</context> <context> <name>RecentRequestsTableModel</name> <message> @@ -865,7 +1203,15 @@ Adresa:%4 <source>(no label)</source> <translation>(bez oznake)</translation> </message> - </context> + <message> + <source>(no message)</source> + <translation>(bez poruke)</translation> + </message> + <message> + <source>(no amount)</source> + <translation>(bez iznosa)</translation> + </message> +</context> <context> <name>SendCoinsDialog</name> <message> @@ -873,18 +1219,46 @@ Adresa:%4 <translation>Slanje novca</translation> </message> <message> + <source>Quantity:</source> + <translation>Količina:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>Bajtova:</translation> + </message> + <message> <source>Amount:</source> <translation>Iznos:</translation> </message> <message> + <source>Priority:</source> + <translation>Prioriteta:</translation> + </message> + <message> + <source>Fee:</source> + <translation>Naknada:</translation> + </message> + <message> + <source>Change:</source> + <translation>Vraćeno:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> - <translation>Pošalji k nekoliko primatelja odjednom</translation> + <translation>Pošalji novce većem broju primatelja u jednoj transakciji</translation> </message> <message> <source>Add &Recipient</source> <translation>&Dodaj primatelja</translation> </message> <message> + <source>Clear all fields of the form.</source> + <translation>Obriši sva polja</translation> + </message> + <message> + <source>Dust:</source> + <translation>Prah:</translation> + </message> + <message> <source>Clear &All</source> <translation>Obriši &sve</translation> </message> @@ -913,24 +1287,16 @@ Adresa:%4 <translation>ili</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Adresa primatelja je nevaljala, molimo provjerite je ponovo.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Iznos mora biti veći od 0.</translation> </message> <message> <source>The amount exceeds your balance.</source> - <translation>Iznos je veći od stanja računa.</translation> + <translation>Iznos je veći od raspoložljivog stanja novčanika.</translation> </message> <message> <source>The total exceeds your balance when the %1 transaction fee is included.</source> - <translation>Iznos je veći od stanja računa kad se doda naknada za transakcije od %1.</translation> - </message> - <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Pronašli smo adresu koja se ponavlja. U svakom plaćanju program može svaku adresu koristiti samo jedanput.</translation> + <translation>Iznos je veći od stanja novčanika kad se doda naknada za transakcije od %1.</translation> </message> <message> <source>(no label)</source> @@ -986,10 +1352,6 @@ Adresa:%4 <translation>&Potpišite poruku</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Možete potpisati poruke sa svojom adresom kako bi dokazali da ih posjedujete. Budite oprezni da ne potpisujete ništa mutno, jer bi vas phishing napadi mogli na prevaru natjerati da prepišete svoj identitet njima. Potpisujte samo detaljno objašnjene izjave sa kojima se slažete.</translation> - </message> - <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1030,7 +1392,7 @@ Adresa:%4 <name>SplashScreen</name> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Jezgra</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>[testnet]</source> @@ -1151,7 +1513,7 @@ Adresa:%4 </message> <message> <source>This pane shows a detailed description of the transaction</source> - <translation>Ova panela prikazuje detaljni opis transakcije</translation> + <translation>Ovaj prozor prikazuje detaljni opis transakcije</translation> </message> </context> <context> @@ -1165,10 +1527,6 @@ Adresa:%4 <translation>Tip</translation> </message> <message> - <source>Address</source> - <translation>Adresa</translation> - </message> - <message> <source>Open until %1</source> <translation>Otvoren do %1</translation> </message> @@ -1178,13 +1536,17 @@ Adresa:%4 </message> <message> <source>This block was not received by any other nodes and will probably not be accepted!</source> - <translation>Generirano - Upozorenje: ovaj blok nije bio primljen od strane bilo kojeg drugog noda i vjerojatno neće biti prihvaćen!</translation> + <translation>Ovaj blok nije bio primljen od strane bilo kojeg drugog čvora i vjerojatno neće biti prihvaćen!</translation> </message> <message> <source>Generated but not accepted</source> <translation>Generirano, ali nije prihvaćeno</translation> </message> <message> + <source>Label</source> + <translation>Oznaka</translation> + </message> + <message> <source>Received with</source> <translation>Primljeno s</translation> </message> @@ -1221,10 +1583,6 @@ Adresa:%4 <translation>Vrsta transakcije.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Odredište transakcije</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Iznos odbijen od ili dodan k saldu.</translation> </message> @@ -1269,7 +1627,7 @@ Adresa:%4 </message> <message> <source>To yourself</source> - <translation>Tebi</translation> + <translation>Samom sebi</translation> </message> <message> <source>Mined</source> @@ -1289,19 +1647,23 @@ Adresa:%4 </message> <message> <source>Copy address</source> - <translation>Kopirati adresu</translation> + <translation>Kopiraj adresu</translation> </message> <message> <source>Copy label</source> - <translation>Kopirati oznaku</translation> + <translation>Kopiraj oznaku</translation> </message> <message> <source>Copy amount</source> <translation>Kopiraj iznos</translation> </message> <message> + <source>Copy transaction ID</source> + <translation>Kopiraj ID transakcije</translation> + </message> + <message> <source>Edit label</source> - <translation>Izmjeniti oznaku</translation> + <translation>Izmjeni oznaku</translation> </message> <message> <source>Show transaction details</source> @@ -1373,7 +1735,7 @@ Adresa:%4 </message> <message> <source>Backup Wallet</source> - <translation>Backup novčanika</translation> + <translation>Arhiviranje novčanika</translation> </message> <message> <source>Wallet Data (*.dat)</source> @@ -1381,7 +1743,7 @@ Adresa:%4 </message> <message> <source>Backup Failed</source> - <translation>Backup nije uspio</translation> + <translation>Arhiviranje nije uspjelo</translation> </message> </context> <context> @@ -1392,7 +1754,7 @@ Adresa:%4 </message> <message> <source>Specify data directory</source> - <translation>Odredi direktorij za datoteke</translation> + <translation>Odaberi direktorij za datoteke</translation> </message> <message> <source>Specify your own public address</source> @@ -1420,15 +1782,15 @@ Adresa:%4 </message> <message> <source>Connect only to the specified node(s)</source> - <translation>Poveži se samo sa određenim nodom</translation> + <translation>Poveži se samo sa određenim čvorom/čvorovima</translation> </message> <message> <source>Error: Disk space is low!</source> - <translation>Pogreška: Nema prostora na disku!</translation> + <translation>Pogreška: Nema dovoljno prostora na disku!</translation> </message> <message> <source>Imports blocks from external blk000??.dat file</source> - <translation>Importiraj blokove sa vanjskog blk000??.dat fajla</translation> + <translation>Uvozi blokove sa vanjske blk000??.dat datoteke</translation> </message> <message> <source>Information</source> @@ -1439,6 +1801,10 @@ Adresa:%4 <translation>Šalji trace/debug informacije na konzolu umjesto u debug.log datoteku</translation> </message> <message> + <source>Start minimized</source> + <translation>Pokreni minimiziran</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Pokušaj koristiti UPnP da otvoriš port za uslugu (default: 1 when listening)</translation> </message> @@ -1476,7 +1842,7 @@ Adresa:%4 </message> <message> <source>Allow DNS lookups for -addnode, -seednode and -connect</source> - <translation>Dozvoli DNS upite za dodavanje nodova i povezivanje</translation> + <translation>Dozvoli DNS upite za -addnode, -seednode i -connect</translation> </message> <message> <source>Loading addresses...</source> @@ -1484,11 +1850,11 @@ Adresa:%4 </message> <message> <source>Error loading wallet.dat: Wallet corrupted</source> - <translation>Greška kod učitavanja wallet.dat: Novčanik pokvaren</translation> + <translation>Greška kod učitavanja datoteke wallet.dat: Novčanik pokvaren</translation> </message> <message> <source>Error loading wallet.dat</source> - <translation>Greška kod učitavanja wallet.dat</translation> + <translation>Greška kod učitavanja datoteke wallet.dat</translation> </message> <message> <source>Invalid -proxy address: '%s'</source> @@ -1496,7 +1862,7 @@ Adresa:%4 </message> <message> <source>Invalid amount for -paytxfee=<amount>: '%s'</source> - <translation>Nevaljali iznos za opciju -paytxfee=<amount>: '%s'</translation> + <translation>Nevaljali iznos za opciju -paytxfee=<iznos>: '%s'</translation> </message> <message> <source>Insufficient funds</source> @@ -1508,7 +1874,7 @@ Adresa:%4 </message> <message> <source>Add a node to connect to and attempt to keep the connection open</source> - <translation>Unesite nod s kojim se želite spojiti and attempt to keep the connection open</translation> + <translation>Doda čvor s kojim se želite povezati i nastoji održati vezu otvorenu</translation> </message> <message> <source>Loading wallet...</source> @@ -1524,7 +1890,7 @@ Adresa:%4 </message> <message> <source>Rescanning...</source> - <translation>Rescaniranje</translation> + <translation>Ponovno pretraživanje...</translation> </message> <message> <source>Done loading</source> diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index a95f9412c3..fd476611ee 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -1,4 +1,4 @@ -<TS language="hu" version="2.1"> +<TS language="hu" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -87,7 +87,7 @@ </message> <message> <source>Comma separated file (*.csv)</source> - <translation>Vesszővel elválasztott fájl (*. csv)</translation> + <translation>Vesszővel elválasztott fájl (*.csv)</translation> </message> <message> <source>Exporting Failed</source> @@ -156,10 +156,6 @@ <translation>Jelszó megváltoztatása</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Írd be a tárca régi és új jelszavát.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Biztosan titkosítani akarod a tárcát?</translation> </message> @@ -188,10 +184,6 @@ <translation>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.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>A Bitcoin Core most bezár, hogy befejezze a titkosítást. Ne feledd: a tárca titkosítása nem nyújt teljes védelmet azzal szemben, hogy adathalász programok megfertőzzék a számítógéped és ellopják a bitcoinjaid.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>A tárca titkosítása sikertelen.</translation> </message> @@ -311,10 +303,6 @@ <translation>Bitcoin küldése megadott címre</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Bitcoin konfigurációs opciók</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Biztonsági másolat készítése a tárcáról egy másik helyre</translation> </message> @@ -422,10 +410,6 @@ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> <translation>A Bitcoin Core súgóüzenet megjelenítése a Bitcoin lehetséges parancssori kapcsolóival.</translation> </message> - <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n aktív kapcsolat a Bitcoin-hálózattal</numerusform><numerusform>%n aktív kapcsolat a Bitcoin-hálózattal</numerusform></translation> - </message> <message> <source>No block source available...</source> <translation>Blokk forrása ismeretlen...</translation> @@ -434,22 +418,10 @@ <source>%n hour(s)</source> <translation><numerusform>%n óra</numerusform><numerusform>%n óra</numerusform></translation> </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n nap</numerusform><numerusform>%n nap</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n week(s)</source> - <translation><numerusform>%n hét</numerusform><numerusform>%n hét</numerusform></translation> - </message> <message> <source>%1 and %2</source> <translation>%1 és %2</translation> </message> - <message numerus="yes"> - <source>%n year(s)</source> - <translation><numerusform>%n év</numerusform><numerusform>%n év</numerusform></translation> - </message> <message> <source>%1 behind</source> <translation>%1 lemaradás</translation> @@ -483,6 +455,18 @@ <translation>Frissítés...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Dátum: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Típus: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Tranzakció elküldve.</translation> </message> @@ -491,18 +475,6 @@ <translation>Beérkező tranzakció</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Dátum: %1 -Összeg: %2 -Típus: %3 -Cím: %4 -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>A tárca <b>titkosítva</b> és jelenleg <b>nyitva</b>.</translation> </message> @@ -630,7 +602,7 @@ Cím: %4 </message> <message> <source>Copy dust</source> - <translation>Por-határ másolása</translation> + <translation>Visszajáró másolása</translation> </message> <message> <source>Copy change</source> @@ -693,10 +665,6 @@ Cím: %4 <translation>nem</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Ez a címke piros lesz, ha tranzakció mérete nagyobb 1000 byte-nál.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Legalább %1 díj szüksége kB-onként.</translation> </message> @@ -709,14 +677,6 @@ Cím: %4 <translation>Nagyobb prioritású tranzakciók nagyobb valószínűséggel kerülnek be egy blokkba.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Ez a címke piros lesz, ha a prioritás közepesnél alacsonyabb.</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Ez a címke piros lesz, ha valamelyik elfogadó kevesebbet kap mint %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(nincs címke)</translation> </message> @@ -833,31 +793,6 @@ Cím: %4 <source>command-line options</source> <translation>parancssoros opciók</translation> </message> - <message> - <source>UI options</source> - <translation>UI opciók</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Nyelvbeállítás, például "de_DE" (alapértelmezett: rendszer nyelve)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Indítás lekicsinyítve -</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>SLL gyökér-igazolások megadása fizetési kérelmekhez (alapértelmezett: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Indítóképernyő mutatása induláskor (alapértelmezett: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Adatkönyvtár kiválasztása induláskor (alapbeállítás: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -870,6 +805,10 @@ Cím: %4 <translation>Üdvözlünk a Bitcoin Core-ban.</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>Use the default data directory</source> <translation>Az alapértelmezett adat könyvtár használata</translation> </message> @@ -924,14 +863,6 @@ Cím: %4 <translation>&Fő</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Induljon el a Bitcoin a számítógép bekapcsolásakor</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Induljon el a számítógép bekapcsolásakor</translation> - </message> - <message> <source>MB</source> <translation>MB</translation> </message> @@ -960,6 +891,14 @@ Cím: %4 <translation>&Hálózat</translation> </message> <message> + <source>&Start Bitcoin Core on system login</source> + <translation>A Bitcoin elindítása bejelentkezéskor</translation> + </message> + <message> + <source>Expert</source> + <translation>szakértő</translation> + </message> + <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> <translation>A Bitcoin-kliens portjának automatikus megnyitása a routeren. Ez csak akkor működik, ha a routered támogatja az UPnP-t és az engedélyezve is van rajta.</translation> </message> @@ -968,6 +907,10 @@ Cím: %4 <translation>&UPnP port-feltérképezés</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Csatlakozás a Bitcoin hálózatához SOCKS5 proxyn keresztül</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>Proxy &IP:</translation> </message> @@ -992,10 +935,6 @@ Cím: %4 <translation>&Kicsinyítés a tálcára az eszköztár helyett</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Az alkalmazásból való kilépés helyett az eszköztárba kicsinyíti az alkalmazást az ablak bezárásakor. Ez esetben az alkalmazás csak a Kilépés menüponttal zárható be.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>K&icsinyítés záráskor</translation> </message> @@ -1008,10 +947,6 @@ Cím: %4 <translation>Felhasználófelület nye&lve:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Itt beállíthatod a felhasználófelület nyelvét. Ez a beállítás a Bitcoin ujraindítása után lép érvénybe.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Mértékegység:</translation> </message> @@ -1098,11 +1033,7 @@ Cím: %4 <source>Recent transactions</source> <translation>A legutóbbi tranzakciók</translation> </message> - <message> - <source>out of sync</source> - <translation>Nincs szinkronban.</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> <message> @@ -1117,6 +1048,10 @@ Cím: %4 <context> <name>PeerTableModel</name> <message> + <source>User Agent</source> + <translation>User Agent</translation> + </message> + <message> <source>Ping Time</source> <translation>Ping idő</translation> </message> @@ -1144,10 +1079,6 @@ Cím: %4 <translation>%1 mp</translation> </message> <message> - <source>NETWORK</source> - <translation>HÁLÓZAT</translation> - </message> - <message> <source>N/A</source> <translation>Nem elérhető</translation> </message> @@ -1242,10 +1173,30 @@ Cím: %4 <translation>Verzió</translation> </message> <message> + <source>User Agent</source> + <translation>User Agent</translation> + </message> + <message> <source>Services</source> <translation>Szolgáltatások</translation> </message> <message> + <source>Last Send</source> + <translation>Legutóbbi küldés</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Legutóbbi fogadás</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Küldött bájtok</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Fogadott bájtok</translation> + </message> + <message> <source>Ping Time</source> <translation>Ping idő</translation> </message> @@ -1290,10 +1241,6 @@ Cím: %4 <translation>Konzol törlése</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Üdv a Bitcoin RPC konzoljában!</translation> - </message> - <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Navigálhat a fel és le nyilakkal, és <b>Ctrl-L</b> -vel törölheti a képernyőt.</translation> </message> @@ -1321,6 +1268,10 @@ Cím: %4 <source>never</source> <translation>soha</translation> </message> + <message> + <source>Unknown</source> + <translation>Ismeretlen</translation> + </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -1329,6 +1280,10 @@ Cím: %4 <translation>Címke:</translation> </message> <message> + <source>&Message:</source> + <translation>&Üzenet:</translation> + </message> + <message> <source>Clear</source> <translation>Törlés</translation> </message> @@ -1462,6 +1417,14 @@ Cím: %4 <translation>Visszajáró:</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Tranzakciós díj</translation> + </message> + <message> + <source>Hide</source> + <translation>Elrejtés</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Küldés több címzettnek egyszerre</translation> </message> @@ -1526,10 +1489,6 @@ Cím: %4 <translation>vagy</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>A címzett címe érvénytelen, kérlek, ellenőrizd.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>A fizetendő összegnek nagyobbnak kell lennie 0-nál.</translation> </message> @@ -1542,10 +1501,6 @@ Cím: %4 <translation>A küldeni kívánt összeg és a %1 tranzakciós díj együtt meghaladja az egyenlegeden rendelkezésedre álló összeget.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Többször szerepel ugyanaz a cím. Egy küldési műveletben egy címre csak egyszer lehet küldeni.</translation> - </message> - <message> <source>(no label)</source> <translation>(nincs címke)</translation> </message> @@ -1612,10 +1567,6 @@ Cím: %4 <translation>Üzenet aláírása...</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Aláírhat a címeivel üzeneteket, amivel bizonyíthatja, hogy a címek az önéi. Vigyázzon, hogy ne írjon alá semmi félreérthetőt, mivel a phising támadásokkal megpróbálhatják becsapni, hogy az azonosságát átírja másokra. Csak olyan részletes állításokat írjon alá, amivel egyetért.</translation> - </message> - <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1656,10 +1607,6 @@ Cím: %4 <translation>Üzenet ellenőrzése</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Írja be az aláírás címét, az üzenetet (ügyelve arra, hogy az új-sor, szóköz, tab, stb. karaktereket is pontosan) és az aláírást az üzenet ellenőrzéséhez. Ügyeljen arra, ne gondoljon többet az aláírásról, mint amennyi az aláírt szövegben ténylegesen áll, hogy elkerülje a köztes-ember (man-in-the-middle) támadást.</translation> - </message> - <message> <source>The entered address is invalid.</source> <translation>A megadott cím nem érvényes.</translation> </message> @@ -1704,7 +1651,7 @@ Cím: %4 </message> <message> <source>The Bitcoin Core developers</source> - <translation>A Bitcoin fejlesztői</translation> + <translation>A Bitcoin Core fejlesztői</translation> </message> <message> <source>[testnet]</source> @@ -1722,7 +1669,7 @@ Cím: %4 <name>TransactionDesc</name> <message> <source>Open until %1</source> - <translation>Megnyitva %1-ig</translation> + <translation>%1-ig megnyitva</translation> </message> <message> <source>%1/unconfirmed</source> @@ -1768,10 +1715,6 @@ Cím: %4 <source>Credit</source> <translation>Jóváírás</translation> </message> - <message numerus="yes"> - <source>matures in %n more block(s)</source> - <translation><numerusform>beérik %n blokk múlva</numerusform><numerusform>beérik %n blokk múlva</numerusform></translation> - </message> <message> <source>not accepted</source> <translation>elutasítva</translation> @@ -1828,10 +1771,6 @@ Cím: %4 <source>, has not been successfully broadcast yet</source> <translation>, még nem sikerült elküldeni.</translation> </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>%n további blokkra megnyitva</numerusform><numerusform>%n további blokkra megnyitva</numerusform></translation> - </message> <message> <source>unknown</source> <translation>ismeretlen</translation> @@ -1859,14 +1798,6 @@ Cím: %4 <translation>Típus</translation> </message> <message> - <source>Address</source> - <translation>Cím</translation> - </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>%n további blokkra megnyitva</numerusform><numerusform>%n további blokkra megnyitva</numerusform></translation> - </message> - <message> <source>Open until %1</source> <translation>%1-ig megnyitva</translation> </message> @@ -1887,6 +1818,14 @@ Cím: %4 <translation>Offline</translation> </message> <message> + <source>Label</source> + <translation>Címke</translation> + </message> + <message> + <source>Unconfirmed</source> + <translation>Megerősítetlen:</translation> + </message> + <message> <source>Received with</source> <translation>Erre a címre</translation> </message> @@ -1923,10 +1862,6 @@ Cím: %4 <translation>Tranzakció típusa.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>A tranzakció címzettjének címe.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Az egyenleghez jóváírt vagy ráterhelt összeg.</translation> </message> @@ -2018,6 +1953,10 @@ Cím: %4 <translation>Az exportálás sikertelen volt</translation> </message> <message> + <source>Exporting Successful</source> + <translation>Sikeres exportálás</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Vesszővel elválasztott fájl (*.csv)</translation> </message> @@ -2071,7 +2010,7 @@ Cím: %4 <name>WalletView</name> <message> <source>&Export</source> - <translation>&Exportálás...</translation> + <translation>&Exportálás</translation> </message> <message> <source>Export the data in the current tab to a file</source> @@ -2150,10 +2089,6 @@ Cím: %4 <translation>Sérült blokk-adatbázis észlelve</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Saját IP-cím felfedezése (alapértelmezett: 1, amikor figyel és nem használt a -externalip)</translation> - </message> - <message> <source>Do you want to rebuild the block database now?</source> <translation>Újra akarod építeni a blokk adatbázist most?</translation> </message> @@ -2194,10 +2129,6 @@ Cím: %4 <translation>Nincs elég fájlleíró. </translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Blokklánc index újraalkotása az alábbi blk000??.dat fájlokból</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>Blokkok ellenőrzése...</translation> </message> @@ -2206,10 +2137,26 @@ Cím: %4 <translation>Tárca ellenőrzése...</translation> </message> <message> + <source>Wallet options:</source> + <translation>Tárca beállítások:</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Az adatbázist újra kell építeni -reindex használatával (módosítás -tindex).</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Adatkönyvtár kiválasztása induláskor (alapbeállítás: 0)</translation> + </message> + <message> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>Copyright (C) 2009-%i A Bitcoin Core Fejlesztői</translation> + </message> + <message> + <source>Error reading from database, shutting down.</source> + <translation>Hiba az adatbázis olvasásakor, leállítás</translation> + </message> + <message> <source>Information</source> <translation>Információ</translation> </message> @@ -2226,10 +2173,27 @@ Cím: %4 <translation>trace/debug információ küldése a konzolra a debog.log fájl helyett</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>SLL gyökér-igazolások megadása fizetési kérelmekhez (alapértelmezett: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Nyelvbeállítás, például "de_DE" (alapértelmezett: rendszer nyelve)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Indítóképernyő mutatása induláskor (alapértelmezett: 1)</translation> + </message> + <message> <source>Signing transaction failed</source> <translation>Tranzakció aláírása sikertelen</translation> </message> <message> + <source>Start minimized</source> + <translation>Indítás lekicsinyítve +</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Ez egy kísérleti szoftver.</translation> </message> diff --git a/src/qt/locale/bitcoin_id_ID.ts b/src/qt/locale/bitcoin_id_ID.ts index bdc67a55d1..6855d11c80 100644 --- a/src/qt/locale/bitcoin_id_ID.ts +++ b/src/qt/locale/bitcoin_id_ID.ts @@ -1,4 +1,4 @@ -<TS language="id_ID" version="2.1"> +<TS language="id_ID" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -148,10 +148,6 @@ <translation>Ubah kata kunci</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Masukkan kata kunci lama dan baru ke dompet ini.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Konfirmasi enkripsi dompet</translation> </message> @@ -172,10 +168,6 @@ <translation>Dompet terenkripsi</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin akan menutup untuk menyelesaikan proses enkripsi. Ingat bahwa dengan mengenkripsi dompet Anda tidak sepenuhnya melindungi bitcoin Anda dari perangkat lunak berbahaya yang menginfeksi komputer Anda.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>Enkripsi dompet gagal</translation> </message> @@ -291,10 +283,6 @@ <translation>Kirim koin ke alamat Bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Ubah pilihan konfigurasi untuk Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Cadangkan dompet ke lokasi lain</translation> </message> @@ -471,18 +459,6 @@ <translation>Transaksi diterima</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Tanggal: %1 -Nilai: %2 -Jenis: %3 -Alamat: %4 -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Dompet saat ini <b>terenkripsi</b> dan <b>terbuka</b></translation> </message> @@ -661,10 +637,6 @@ Alamat: %4 <translation>tidak</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Label ini akan berubah merah, jika ukuran transaksi lebih besar dari 1000 byte.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Berarti perlu biaya lebih dari %1 untuk setiap kB.</translation> </message> @@ -677,14 +649,6 @@ Alamat: %4 <translation>Makin penting transaksinya, makin kemungkinan akan termasuk dalam blok.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Label ini akan berubah merah, jika prioritas lebih kecil dari "medium".</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Label ini akan berubah merah, jika setiap penerima menerima nilai lebih kecil dari %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(tidak ada label)</translation> </message> @@ -797,23 +761,7 @@ Alamat: %4 <source>command-line options</source> <translation>pilihan perintah-baris</translation> </message> - <message> - <source>UI options</source> - <translation>pilihan UI</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Atur bahasa, sebagai contoh "id_ID" (standar: system locale)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Memulai terminimalisi</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Tampilkan layar pembuka saat nyala (standar: 1)</translation> - </message> - </context> +</context> <context> <name>Intro</name> <message> @@ -879,14 +827,6 @@ Alamat: %4 <translation>&Utama</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Menyalakan Bitcoin secara otomatis setelah masuk ke dalam sistem.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Menyalakan Bitcoin pada login sistem</translation> - </message> - <message> <source>MB</source> <translation>MB</translation> </message> @@ -967,10 +907,6 @@ Alamat: %4 <translation>&Meminilisasi ke tray daripada taskbar</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Meminimalkan tanpa keluar dari aplikasi saat jendela ditutup. Apabila pilihan ini diaktifkan, aplikasi hanya bisa ditutup dengan memilih Keluar di menu Berkas.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&eminilisasi saat tutup</translation> </message> @@ -983,10 +919,6 @@ Alamat: %4 <translation>&Bahasa Antarmuka Pengguna:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Tampilan bahasa pengguna dapat diatur disini. Pengaturan ini akan berpengaruh setelah memulai kembali aplikasi Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Unit untuk menunjukkan nilai:</translation> </message> @@ -1023,10 +955,6 @@ Alamat: %4 <translation>Restart klien diperlukan untuk mengaktifkan perubahan.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Klien akan dimatikan, apakah anda hendak melanjutkan?</translation> - </message> - <message> <source>This change would require a client restart.</source> <translation>Perubahan ini akan memerlukan restart klien</translation> </message> @@ -1077,11 +1005,7 @@ Alamat: %4 <source>Your current total balance</source> <translation>Jumlah saldo Anda sekarang</translation> </message> - <message> - <source>out of sync</source> - <translation>tidak tersinkron</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> <message> @@ -1257,18 +1181,10 @@ Alamat: %4 <translation>Berkas catatan debug</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Buka berkas catatan debug Bitcoin dari direktori data sekarang. Hal ini dapat memakan waktu beberapa detik untuk berkas catatan yang besar.</translation> - </message> - <message> <source>Clear console</source> <translation>Bersihkan konsol</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Selamat datang ke konsol RPC Bitcoin.</translation> - </message> - <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Gunakan panah keatas dan kebawah untuk menampilkan sejarah, dan <b>Ctrl-L</b> untuk bersihkan layar.</translation> </message> @@ -1581,10 +1497,6 @@ Alamat: %4 <translation>atau</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Alamat penerima tidak sah, silakan periksa sekali lagi.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Nilai yang dibayar harus lebih besar dari 0.</translation> </message> @@ -1597,10 +1509,6 @@ Alamat: %4 <translation>Jumlah melebihi saldo Anda ketika biaya transaksi %1 ditambahkan.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Ditemukan alamat ganda, hanya dapat mengirim ke tiap alamat sekali per operasi pengiriman.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Gagal membuat transaksi!</translation> </message> @@ -1672,18 +1580,10 @@ Alamat: %4 <translation>Pesan:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Permintaan pembayaran terverifikasi.</translation> - </message> - <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Masukkan label untuk alamat ini untuk dimasukan dalam daftar alamat yang pernah digunakan</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Permintaan pembayaran tidak terverifikasi.</translation> - </message> - <message> <source>Pay To:</source> <translation>Kirim Ke:</translation> </message> @@ -1997,10 +1897,6 @@ Alamat: %4 <translation>Jenis</translation> </message> <message> - <source>Address</source> - <translation>Alamat</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Terlalu muda (cuma %1 konfirmasi, akan siap sesudah %2) </translation> </message> @@ -2029,6 +1925,10 @@ Alamat: %4 <translation>Tidak terhubung</translation> </message> <message> + <source>Label</source> + <translation>Label</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Belum dikonfirmasi</translation> </message> @@ -2077,10 +1977,6 @@ Alamat: %4 <translation>Jenis transaksi.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Alamat tujuan dari transaksi.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Nilai dihapus dari atau ditambahkan ke saldo.</translation> </message> @@ -2351,10 +2247,6 @@ Alamat: %4 <translation>Menemukan database blok yang rusak </translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Cari alamat IP Anda sendiri (biasanya: 1 saat mendengarkan dan -externalip tidak terpilih)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Jangan memuat dompet dan menonaktifkan panggilan dompet RPC</translation> </message> @@ -2455,6 +2347,14 @@ Alamat: %4 <translation>Kirim info jejak/debug ke konsol bukan berkas debug.log</translation> </message> <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Atur bahasa, sebagai contoh "id_ID" (standar: system locale)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Tampilkan layar pembuka saat nyala (standar: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Mengecilkan berkas debug.log saat klien berjalan (Standar: 1 jika tidak -debug)</translation> </message> @@ -2463,6 +2363,10 @@ Alamat: %4 <translation>Tandatangani transaksi tergagal</translation> </message> <message> + <source>Start minimized</source> + <translation>Memulai terminimalisi</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Nilai transaksi terlalu kecil</translation> </message> @@ -2483,10 +2387,6 @@ Alamat: %4 <translation>Peringatan</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Perhatian: Versi ini sudah lama, perlu ditingkatkan!</translation> - </message> - <message> <source>Zapping all transactions from wallet...</source> <translation>Setiap transaksi dalam dompet sedang di-'Zap'...</translation> </message> diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index 23eec1bf3e..d3cc576979 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -1,4 +1,4 @@ -<TS language="it" version="2.1"> +<TS language="it" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ <translation>Cambia la passphrase</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Inserisci la vecchia e la nuova passphrase per il portamonete.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Conferma la cifratura del portamonete</translation> </message> @@ -172,6 +168,10 @@ <translation>Si è sicuri di voler cifrare il portamonete?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -188,8 +188,8 @@ <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin si chiuderà per portare a termine il processo di cifratura. Ricorda che cifrare il tuo portamonete non può fornire una protezione totale contro i furti causati da infezioni malware.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Inserisci la vecchia e la nuova passphrase per il portamonete.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>Invia fondi ad un indirizzo Bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Modifica opzioni di configurazione per Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Effettua il backup del portamonete</translation> </message> @@ -403,6 +399,10 @@ <translation>&Informazioni su Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modifica opzioni di configurazione per Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Mostra la lista degli indirizzi di invio utilizzati</translation> </message> @@ -431,6 +431,10 @@ <translation>Nessuna fonte di blocchi disponibile...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Elaborato %n blocco dello storico transazioni.</numerusform><numerusform>Elaborati %n blocchi dello storico transazioni.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n ora</numerusform><numerusform>%n ore</numerusform></translation> </message> @@ -478,36 +482,49 @@ <source>Up to date</source> <translation>Aggiornato</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>Processati %n blocchi dello storico transazioni.</numerusform><numerusform>Processati %n blocchi dello storico delle transazioni.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>In aggiornamento...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Transazione inviata</translation> + <source>Date: %1 +</source> + <translation>Data: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Transazione ricevuta</translation> + <source>Amount: %1 +</source> + <translation>Quantità: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Data: %1 -Quantità: %2 -Tipo: %3 -Indirizzo: %4 - + <translation>Tipo: %1 </translation> </message> <message> + <source>Label: %1 +</source> + <translation>Etichetta: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Indirizzo: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Transazione inviata</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Transazione ricevuta</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Il portamonete è <b>cifrato</b> ed attualmente <b>sbloccato</b></translation> </message> @@ -698,6 +715,18 @@ Indirizzo: %4 <translation>nessuno</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Questa etichetta diventerà rossa se la dimensione della transazione supererà i 1000 byte.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Questa etichetta diventerà rossa se la priorità sarà inferiore a "media".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Questa etichetta diventerà rossa se uno qualsiasi dei destinatari riceverà un importo inferiore a %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Può variare di +/- %1 satoshi per input.</translation> </message> @@ -710,10 +739,6 @@ Indirizzo: %4 <translation>no</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Questa etichetta diventerà rossa se la dimensione della transazione supererà i 1000 byte.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>In tal caso sarà necessaria una commissione di almeno %1 per ogni kB.</translation> </message> @@ -726,14 +751,6 @@ Indirizzo: %4 <translation>Le transazioni con priorità più alta hanno più probabilità di essere incluse in un blocco.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Questa etichetta diventerà rossa se la priorità sarà inferiore a "media".</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Questa etichetta diventerà rossa se uno qualsiasi dei destinatari riceverà un ammontare inferiore a %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(nessuna etichetta)</translation> </message> @@ -854,30 +871,6 @@ Indirizzo: %4 <source>command-line options</source> <translation>opzioni della riga di comando</translation> </message> - <message> - <source>UI options</source> - <translation>Opzioni UI</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Imposta lingua, ad esempio "it_IT" (predefinito: lingua di sistema)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Avvia ridotto a icona</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Imposta i certificati radice SSL per le richieste di pagamento (predefinito: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostra finestra di presentazione all'avvio (predefinito: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Seleziona la cartella dati all'avvio (predefinito: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -952,14 +945,6 @@ Indirizzo: %4 <translation>&Principale</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Avvia automaticamente Bitcoin una volta effettuato l'accesso al sistema.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Avvia Bitcoin all'accesso al sistema</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Dimensione della cache del &database.</translation> </message> @@ -984,6 +969,14 @@ Indirizzo: %4 <translation>Indirizzo IP del proxy (ad es. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>La lingua dell'interfaccia utente può essere impostata qui. L'applicazione delle modifiche avrà effetto dopo il riavvio di Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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. Per specificare più URL separarli con una barra verticale "|".</translation> @@ -1009,6 +1002,14 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Rete</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Avvia automaticamente Bitcoin Core una volta effettuato l'accesso al sistema.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Avvia Bitcoin Core all'accesso al sistema</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = automatico, <0 = lascia questo numero di core liberi)</translation> </message> @@ -1073,10 +1074,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>&Minimizza nella tray bar invece che sulla barra delle applicazioni</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Riduci ad icona invece di uscire dall'applicazione quando la finestra viene chiusa. Se l'opzione è attiva, l'applicazione terminerà solo dopo aver selezionato Esci dal menu File.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimizza alla chiusura</translation> </message> @@ -1089,10 +1086,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>&Lingua Interfaccia Utente:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>La lingua dell'interfaccia utente può essere impostata qui. L'impostazione avrà effetto dopo il riavvio di Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Unità di misura con cui visualizzare gli importi:</translation> </message> @@ -1129,8 +1122,8 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>È necessario un riavvio del client per applicare le modifiche.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Il client sarà arrestato, vuoi procedere?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Il client sarà arrestato. Si desidera procedere?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1215,10 +1208,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <source>Current total balance in watch-only addresses</source> <translation>Saldo corrente totale negli indirizzi di sola lettura</translation> </message> - <message> - <source>out of sync</source> - <translation>non sincronizzato</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1239,10 +1228,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>La rete della richiesta di pagamento non corrisponde alla rete del client.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Richiesta di pagamento scaduta.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>La richiesta di pagamento non è stata inizializzata.</translation> </message> @@ -1275,10 +1260,18 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Impossibile leggere il file della richiesta di pagamento! Il file della richiesta di pagamento potrebbe non essere valido.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Richiesta di pagamento scaduta.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Le richieste di pagamento non verificate verso script di pagamento personalizzati non sono supportate.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Richiesta di pagamento non valida.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Rimborso da %1</translation> </message> @@ -1318,8 +1311,8 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>User Agent</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Indirizzo/Nome host</translation> + <source>Node/Service</source> + <translation>Nodo/Servizio</translation> </message> <message> <source>Ping Time</source> @@ -1353,14 +1346,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>RETE</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>SCONOSCIUTO</translation> - </message> - <message> <source>None</source> <translation>Nessuno</translation> </message> @@ -1451,6 +1436,10 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Numero attuale di blocchi</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>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.</translation> + </message> + <message> <source>Received</source> <translation>Ricevuto</translation> </message> @@ -1519,6 +1508,10 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Tempo di Ping</translation> </message> <message> + <source>Time Offset</source> + <translation>Scarto Temporale</translation> + </message> + <message> <source>Last block time</source> <translation>Ora del blocco più recente</translation> </message> @@ -1559,16 +1552,12 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>File log del Debug</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Apri il file log del debug di Bitcoin dalla cartella dati attuale. Può richiedere alcuni secondi per file di log di grandi dimensioni.</translation> - </message> - <message> <source>Clear console</source> <translation>Cancella console</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Benvenuto nella console RPC di Bitcoin.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Benvenuto nella console RPC di Bitcoin Core.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1859,14 +1848,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>minimizza le impostazioni di commissione</translation> </message> <message> - <source>Minimize</source> - <translation>Minimizza</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Se la commissione personalizzata è impostata su 1000 satoshi e la transazione è di soli 250 byte, allora "per kilobyte" paga solo 250 satoshi di commissione, mentre "somma almeno" paga 1000 satoshi. Per transazioni più grandi di un kilobyte, entrambe le opzioni pagano al kilobyte.</translation> - </message> - <message> <source>per kilobyte</source> <translation>per kilobyte</translation> </message> @@ -1875,6 +1856,10 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Se la commissione personalizzata è impostata su 1000 satoshi e la transazione è di soli 250 byte, allora "per kilobyte" paga solo 250 satoshi di commissione, mentre "somma almeno" paga 1000 satoshi. Per transazioni più grandi di un kilobyte, entrambe le opzioni pagano al kilobyte.</translation> </message> <message> + <source>Hide</source> + <translation>Nascondi</translation> + </message> + <message> <source>total at least</source> <translation>somma almeno</translation> </message> @@ -1995,10 +1980,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>o</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>L'indirizzo del beneficiario non è valido, si prega di ricontrollare.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>L'importo da pagare deve essere maggiore di 0.</translation> </message> @@ -2011,10 +1992,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Il totale è superiore al tuo saldo attuale includendo la commissione di %1.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Rilevato un indirizzo duplicato. È possibile inviare bitcoin una sola volta a ciascun indirizzo durante un'operazione di invio.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Creazione transazione fallita!</translation> </message> @@ -2023,16 +2000,24 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> + <source>A fee higher than %1 is considered an absurdly high fee.</source> <translation>Una commissione maggiore di %1 è considerata irragionevolmente elevata.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Richiesta di pagamento scaduta.</translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Paga solamente la commissione minima di %1</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Inizio delle conferme stimato entro %1 blocchi.</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>L'indirizzo del beneficiario non è valido. Si prega di ricontrollare.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Rilevato un indirizzo duplicato Ciascun indirizzo dovrebbe essere utilizzato una sola volta.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2106,12 +2091,24 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Rimuovi questa voce</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>La commissione sarà sottratta dall'importo che si sta inviando. Il beneficiario riceverà un totale di bitcoin inferiore al valore digitato. Nel caso in cui siano stati selezionati più beneficiari la commissione sarà suddivisa in parti uguali.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>S&ottrae la commissione dall'importo</translation> + </message> + <message> <source>Message:</source> <translation>Messaggio:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Questa è una richiesta di pagamento verificata.</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Questa è una richiesta di pagamento non autenticata.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Questa è una richiesta di pagamento autenticata.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2122,10 +2119,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Messaggio incluso nel bitcoin URI e che sarà memorizzato con la transazione per vostro riferimento. Nota: Questo messaggio non sarà inviato attraverso la rete Bitcoin.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Questa è una richiesta di pagamento non verificata.</translation> - </message> - <message> <source>Pay To:</source> <translation>Pagare a:</translation> </message> @@ -2156,8 +2149,8 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>&Firma Messaggio</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Puoi firmare messaggi con i tuoi indirizzi in modo da dimostrarne il possesso. Presta attenzione a non firmare dichiarazioni vaghe, attacchi di phishing potrebbero cercare di spingerti ad apporre la tua firma su di esse. Firma solo dichiarazioni completamente dettagliate e delle quali condividi in pieno il contenuto.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>È possibile firmare messaggi/accordi con i propri indirizzi in modo da dimostrare di poter ricevere bitcoin attraverso di essi. Si consiglia di prestare attenzione a non firmare dichiarazioni vaghe o casuali, attacchi di phishing potrebbero cercare di indurre ad apporre la firma su di esse. Si raccomanda di firmare esclusivamente dichiarazioni completamente dettagliate e delle quali si condivide in pieno il contenuto.</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2212,8 +2205,8 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>&Verifica Messaggio</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Inserisci l'indirizzo del firmatario, il messaggio (assicurandoti di copiare esattamente anche i ritorni a capo, gli spazi, le tabulazioni, etc..) e la firma qui sotto, per verificare il messaggio. Presta attenzione a non vedere nella sola firma più di quanto non sia riportato nel messaggio stesso, in modo da evitare di cadere vittima di attacchi di tipo man-in-the-middle.</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Per verificare il messaggio inserire l'indirizzo del firmatario, il messaggio e la firma nei campi sottostanti, assicurandosi di copiare esattamente anche ritorni a capo, spazi, tabulazioni, etc.. Si raccomanda di non lasciarsi fuorviare dalla firma a leggere più di quanto non sia riportato nel testo del messaggio stesso, in modo da evitare di cadere vittima di attacchi di tipo man-in-the-middle. Si ricorda che la verifica della firma dimostra soltanto che il firmatario può ricevere pagamenti con l'indirizzo corrispondente, non prova l'invio di alcuna transazione.</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2479,10 +2472,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Tipo</translation> </message> <message> - <source>Address</source> - <translation>Indirizzo</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Immaturo (%1 conferme, sarà disponibile fra %2)</translation> </message> @@ -2511,6 +2500,10 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Offline</translation> </message> <message> + <source>Label</source> + <translation>Etichetta</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Non confermata</translation> </message> @@ -2567,8 +2560,8 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Indica se un indirizzo di sola lettura sia o meno coinvolto in questa transazione.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Indirizzo di destinazione della transazione.</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Intento/scopo della transazione definito dall'utente.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2821,16 +2814,16 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Distribuito secondo la licenza software MIT, vedi il file COPYING incluso oppure <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Entra in modalità test di regressione. Questa utilizza una speciale catena in cui i blocchi possono essere risolti istantaneamente.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Esegue un comando quando lo stato di una transazione del portamonete cambia (%s in cmd è sostituito da TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>In questa modalità -genproclimit determina quanti blocchi saranno generati immediatamente.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Commissioni massime totali da includere in una singola transazione dal portamonete. Un'impostazione troppo bassa potrebbe provocare l'annullamento di transazioni di grosse dimensioni (predefinito: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Riduce i requisiti di spazio di archiviazione attraverso la rimozione dei vecchi blocchi (pruning). Questa modalità disabilita le funzionalità di portamonete ed è incompatibile con l'opzione -txindex. Attenzione: il ripristinando questa opzione l'intera blockchain dovrà essere riscaricata. (predefinito: 0 = disabilita il pruning, >%u = dimensione desiderata in MiB per i file dei blocchi)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2845,6 +2838,14 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Impossibile associarsi a %s su questo computer. Probabilmente Bitcoin Core è già in esecuzione.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>ATTENZIONE, il numero di blocchi generati è insolitamente elevato: %d blocchi ricevuti nelle ultime %d ore (%d previsti)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>ATTENZIONE, si consiglia di verificare la connessione di rete: %d blocchi ricevuti nelle ultime %d ore (%d previsti)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Attenzione: -paytxfee è impostato su un valore molto elevato. Questa è la commissione che si paga quando si invia una transazione.</translation> </message> @@ -2901,10 +2902,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Opzioni di Debug/Test:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Scopre il proprio indirizzo IP (predefinito: 1 se in ascolto ed -externalip non è specificato)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Disabilita il portamonete e le relative chiamate RPC</translation> </message> @@ -2965,8 +2962,12 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Connessione ai soli nodi appartenenti alla rete <net> (ipv4, ipv6 o Tor)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Ricostruzione dell'indice della block chain dai file blk000??.dat correnti</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>La modalità prune non può essere configurata con un valore negativo.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>La modalità prune è incompatibile con l'opzione -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2981,10 +2982,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Specifica il file del portamonete (all'interno della cartella dati)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Questa impostazione è destinata all'uso con i test di regressione e per lo sviluppo di applicazioni.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Usa UPnP per mappare la porta di ascolto (predefinito: %u)</translation> </message> @@ -3005,6 +3002,10 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Opzioni portamonete:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Attenzione: questa versione è obsoleta. Aggiornamento necessario!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>È necessario ricostruire il database usando -reindex per cambiare -txindex</translation> </message> @@ -3029,14 +3030,14 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Non è possibile ottenere un lock sulla cartella %s. Probabilmente Bitcoin Core è già in esecuzione.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Limita la quantità di transazioni gratuite ad <n>*1000 byte al minuto (predefinito: %u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>Crea nuovi file con i permessi di default del sistema, invece che con umask 077 (ha effetto solo con funzionalità di portamonete disabilitate)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Scopre i propri indirizzi IP (predefinito: 1 se in ascolto ed -externalip o -proxy non sono specificati)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Errore: attesa per connessioni in arrivo fallita (errore riportato %s)</translation> </message> @@ -3053,10 +3054,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Le commissioni (in BTC/kB) inferiori a questo valore sono considerate pari a zero relativamente alla trasmissione (predefinito: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Le commissioni (in BTC/kB) inferiori a questo valore sono considerate pari a zero relativamente alla creazione della transazione (predefinito: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>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)</translation> </message> @@ -3069,16 +3066,16 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Dimensione massima dei dati in transazioni di trasporto dati che saranno trasmesse ed incluse nei blocchi (predefinito: %u)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>Commissioni massime totali da includere in una singola transazione dal portamonete. Un'impostazione troppo bassa potrebbe provocare il fallimento di transazioni di grosse dimensioni (predefinito: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>La modalità prune è configurata al di sotto del minimo di %d MB. Si prega di utilizzare un valore più elevato.</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Ottiene gli indirizzi dei peer attraverso interrogazioni DNS, in caso di scarsa disponibilità (predefinito: 1 a meno che -connect non sia specificato)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>Richiedi alta priorità per la trasmissione di transazioni a zero o basse commissioni (predefinito:%u )</translation> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Randomizza le credenziali per ogni connessione proxy. Permette la Tor stream isolation (predefinito: %u)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3089,6 +3086,10 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Specifica il numero di thread per la generazione di bitcoin, se abilitata (-1 = tutti i core, predefinito: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>L'importo della transazione risulta troppo basso per l'invio una volta dedotte le commissioni.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -3128,14 +3129,34 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>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</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Per ritornare alla modalità unpruned sarà necessario ricostruire il database utilizzando l'opzione -reindex. L'intera blockchain sarà riscaricata.</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(default: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Accetta richieste REST pubbliche (predefinito: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Attivazione della blockchain migliore...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Impossibile operare con un portamonete in modalità prune.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Impossibile risolvere indirizzo -whitebind: '%s'</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Seleziona la cartella dati all'avvio (predefinito: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Connessione attraverso un proxy SOCKS5</translation> </message> @@ -3216,12 +3237,12 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Supporto RPC per le connessioni HTTP persistenti (predefinito: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Scarta casualmente 1 ogni <n> messaggi di rete</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Ricostruzione dell'indice della block chain dai file blk000??.dat correnti all'avvio</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Altera casualmente 1 ogni <n> messaggi di rete</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Ricevi e visualizza gli alerts della rete P2P (default: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3232,10 +3253,22 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Invia transazioni a zero commissioni se possibile (predefinito: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Imposta i certificati radice SSL per le richieste di pagamento (predefinito: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Imposta lingua, ad esempio "it_IT" (predefinito: lingua di sistema)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Mostra tutte le opzioni di debug (utilizzo: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Mostra finestra di presentazione all'avvio (predefinito: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Riduce il file debug.log all'avvio del client (predefinito: 1 se -debug non è impostato)</translation> </message> @@ -3244,6 +3277,14 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Firma transazione fallita</translation> </message> <message> + <source>Start minimized</source> + <translation>Avvia ridotto a icona</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>L'importo della transazione è troppo basso per pagare la commissione</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Questo è un software sperimentale.</translation> </message> @@ -3264,6 +3305,10 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Transazione troppo grande</translation> </message> <message> + <source>UI Options:</source> + <translation>Opzioni Interfaccia Utente:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Impossibile associarsi a %s su questo computer (l'associazione ha restituito l'errore %s)</translation> </message> @@ -3284,10 +3329,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Attenzione</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Attenzione: questa versione è obsoleta, aggiornamento necessario!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Attenzione: Argomento -benchmark ignorato in quanto non supportato, usare -debug=bench.</translation> </message> @@ -3348,18 +3389,10 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>(1 = mantiene metadati tx, ad es. proprietario account ed informazioni di richiesta di pagamento, 2 = scarta metadati tx)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Scarica l'attività del database dal pool in memoria al log su disco ogni <n> megabyte (predefinito: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Determina quanto sarà approfondita la verifica da parte di -checkblocks (0-4, predefinito: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Abilita il log della priorità di transazione e della commissione per kB quando si generano blocchi (predefinito: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Mantiene l'indice completo delle transazioni usato dalla chiamata rpc getrawtransaction (predefinito: %u)</translation> </message> @@ -3388,18 +3421,10 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Interroga sempre i DNS per ottenere gli indirizzi dei peer (predefinito: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Disabilita la modalità sicura ignorando gli eventi che porterebbero alla sua attivazione (predefinito: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Errore caricamento wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Forza modalità sicura (predefinito: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Genera bitcoin (predefinito: %u)</translation> </message> @@ -3416,10 +3441,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Indirizzo -proxy non valido: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Limita la dimensione della cache delle firme a <n> voci (predefinito: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Resta in attesa di connessioni JSON-RPC su <port> (predefinito: %u o testnet: %u)</translation> </message> @@ -3432,6 +3453,10 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Mantiene al massimo <n> connessioni verso i peer (predefinito: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Configura il portamonete per la trasmissione di transazioni</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Buffer di ricezione massimo per connessione, <n>*1000 byte (predefinito: %u)</translation> </message> @@ -3440,10 +3465,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Buffer di invio massimo per connessione, <n>*1000 byte (predefinito: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Accetta solo block chain corrispondenti ai checkpoint integrati nel codice (predefinito: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Antepone un timestamp all'output del debug (predefinito: %u)</translation> </message> @@ -3456,10 +3477,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Trasmette transazioni non-P2SH multisig (predefinito: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Mantieni in esecuzione un thread per scaricare periodicamente il portamonete (predefinito: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>File del certificato del server (predefinito: %s)</translation> </message> @@ -3480,10 +3497,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Imposta il numero di thread destinati a rispondere alle chiamate RPC (predefinito %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Imposta il flag DB_PRIVATE nell'ambiente di database del portamonete (predefinito: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Specifica il file di configurazione (predefinito: %s)</translation> </message> @@ -3500,10 +3513,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Abilita la spesa di resto non confermato quando si inviano transazioni (predefinito: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Interrompi l'esecuzione dopo aver importato i blocchi dal disco (predefinito: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Soglia di disconnessione per i peer che si comportano in maniera anomala (predefinito: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 99164abab4..e2c22f7f6d 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -1,4 +1,4 @@ -<TS language="ja" version="2.1"> +<TS language="ja" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ <translation>パスフレーズの変更</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>新旧両方のパスフレーズを入力してください。</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>ウォレットの暗号化を確認する</translation> </message> @@ -172,6 +168,10 @@ <translation>本当にウォレットを暗号化しますか?</translation> </message> <message> + <source>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.</source> + <translation>暗号化処理を完了させるため Bitcoin Core をいますぐ終了します。ウォレットの暗号化では、コンピュータに感染したマルウェアなどによるビットコインの盗難から完全に守ることはできないことにご注意ください。</translation> + </message> + <message> <source>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.</source> <translation>重要: 過去のウォレット ファイルのバックアップは、暗号化された新しいウォレット ファイルに取り替える必要があります。セキュリティ上の理由により、暗号化された新しいウォレットを使い始めると、暗号化されていないウォレット ファイルのバックアップはすぐに使えなくなります。</translation> </message> @@ -188,8 +188,8 @@ <translation>ウォレットの新しいパスフレーズを入力してください。<br/><b>10文字以上のランダムな文字</b>で構成されたものか、<b>8単語以上の単語</b>で構成されたパスフレーズを使用してください。</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin は暗号化プロセスを終了するために今すぐ終了します。あなたのコンピュータがマルウェアに感染してコインを盗まれることもあるので、暗号化してもあなたのウォレットを完全に保護できないことを覚えていてください。</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>ウォレットの古いパスフレーズおよび新しいパスフレーズを入力してください。</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>Bitcoin アドレスにコインを送る</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Bitcoin の設定を変更する</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>ウォレットを他の場所にバックアップ</translation> </message> @@ -403,6 +399,10 @@ <translation>ビットコインコアについて (&A)</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Bitcoin Core の設定を編集する</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>使用済みの送金用アドレスとラベルの一覧を表示する</translation> </message> @@ -431,6 +431,10 @@ <translation>利用可能なブロックがありません...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>トランザクション履歴の %n ブロックを処理しました。</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n 時間</numerusform></translation> </message> @@ -478,15 +482,41 @@ <source>Up to date</source> <translation>バージョンは最新です</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>トランザクション履歴の %n ブロックを処理しました。</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>追跡中...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>日付: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>総額: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>タイプ: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>ラベル: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>アドレス: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>送金取引</translation> </message> @@ -495,17 +525,6 @@ <translation>着金取引</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>日付: %1 -総額: %2 -種類: %3 -アドレス: %4</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>ウォレットは<b>暗号化されて、アンロックされています</b></translation> </message> @@ -696,6 +715,18 @@ Address: %4 <translation>なし</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>トランザクションのサイズが1000バイトを超える場合にはこのラベルは赤色になります。</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>優先度が「中」未満の場合、このラベルは赤色になります。</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>受取人のうち誰かの受取額が %1 未満の場合にこのラベルは赤色になります。</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>ひとつの入力につき %1 satoshi 前後ずれることがあります。</translation> </message> @@ -708,10 +739,6 @@ Address: %4 <translation>いいえ</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>トランザクションサイズが1000バイトを超える場合にはこのラベルは赤くなります。</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>これは少なくとも1kBあたり %1 の手数料が必要であることを意味します。</translation> </message> @@ -724,14 +751,6 @@ Address: %4 <translation>より高い優先度を持つトランザクションの方がブロックに取り込まれやすくなります。</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>優先度が「中」未満の場合には、このラベルは赤くなります。</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>少なくともひとつの受取額が %1 を下回る場合にはこのラベルは赤くなります。</translation> - </message> - <message> <source>(no label)</source> <translation>(ラベル無し)</translation> </message> @@ -852,30 +871,6 @@ Address: %4 <source>command-line options</source> <translation>コマンドライン オプション</translation> </message> - <message> - <source>UI options</source> - <translation>UI オプション</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>言語設定 例: "de_DE" (初期値: システムの言語)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>最小化された状態で起動する</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>支払いリクエスト用にSSLルート証明書を設定する(デフォルト:-system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>起動時にスプラッシュ画面を表示する (初期値: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>起動時にデータ ディレクトリを選ぶ (初期値: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -958,14 +953,6 @@ Address: %4 <translation>メイン (&M)</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>システムにログインした時に自動的に Bitcoin を起動します。</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>システムにログインした時に Bitcoin を起動 (&S)</translation> - </message> - <message> <source>Size of &database cache</source> <translation>データベースキャッシュのサイズ (&D)</translation> </message> @@ -990,6 +977,14 @@ Address: %4 <translation>プロキシのIPアドレス (例えば IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>ウィンドウを閉じる際にアプリケーションを終了するのではなく、最小化します。このオプションが有効化された場合、メニューから終了を選択した場合にのみアプリケーションは閉じられます。</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>ユーザ・インタフェイス言語はここで設定できます。この設定はBitcoin Coreの再起動後に有効となります。</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>トランザクションタブのコンテキストメニュー項目に表示する、サードパーティURL (例えばブロックエクスプローラ)。URL中の%sはトランザクションのハッシュ値に置き換えられます。垂直バー | で区切ることで、複数のURLを指定できます。</translation> </message> @@ -1014,6 +1009,14 @@ Address: %4 <translation>ネットワーク (&N)</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>システムにログインした際、自動的にBitcoin Coreを起動する。</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>システムへログインした際にBitcoin Coreを起動する (&S)</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = 自動、0以上 = 指定した数のコアをフリーにする)</translation> </message> @@ -1078,10 +1081,6 @@ Address: %4 <translation>タスクバーの代わりにトレイに最小化 (&M)</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>ウインドウが閉じられる時アプリケーションを終了せずに最小化します。このオプションが有効な時にアプリケーションを終了するにはメニューから終了を選択します。</translation> - </message> - <message> <source>M&inimize on close</source> <translation>閉じる時に最小化 (&i)</translation> </message> @@ -1094,10 +1093,6 @@ Address: %4 <translation>ユーザインターフェースの言語 (&l) :</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>ここでユーザインターフェースの言語を設定できます。設定を反映するには Bitcoin を再起動します。</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>額を表示する単位 (&U) :</translation> </message> @@ -1134,8 +1129,8 @@ Address: %4 <translation>変更を有効化するにはクライアントを再起動する必要があります。</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>クライアントは停止されます。続行しますか?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>クライアントを終了します。続行してもよろしいですか?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1220,10 +1215,6 @@ Address: %4 <source>Current total balance in watch-only addresses</source> <translation>監視限定アドレス内の現在の全残高</translation> </message> - <message> - <source>out of sync</source> - <translation>同期していない</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1244,10 +1235,6 @@ Address: %4 <translation>支払いリクエストのネットワークは現在のクライアントのネットワークに一致しません。</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>支払いのリクエストは期限切れです</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>支払いリクエストは開始されていません。</translation> </message> @@ -1280,10 +1267,18 @@ Address: %4 <translation>支払いリクエストファイルを読み込めませんでした!無効な支払いリクエストファイルにより引き起こされた可能性があります。</translation> </message> <message> + <source>Payment request expired.</source> + <translation>支払いリクエストの期限が切れました。</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>カスタム支払いスクリプトに対する、検証されていない支払いリクエストはサポートされていません。</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>無効な支払いリクエスト。</translation> + </message> + <message> <source>Refund from %1</source> <translation>%1 からの返金</translation> </message> @@ -1323,8 +1318,8 @@ Address: %4 <translation>ユーザエージェント</translation> </message> <message> - <source>Address/Hostname</source> - <translation>アドレス/ホスト名</translation> + <source>Node/Service</source> + <translation>ノード・サービス</translation> </message> <message> <source>Ping Time</source> @@ -1358,14 +1353,6 @@ Address: %4 <translation>%1秒</translation> </message> <message> - <source>NETWORK</source> - <translation>ネットワーク</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>未知</translation> - </message> - <message> <source>None</source> <translation>なし</translation> </message> @@ -1456,6 +1443,10 @@ Address: %4 <translation>現在のブロック数</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>現在のデータディレクトリからBitcoin Coreのデバッグ用ログファイルを開きます。ログファイルが巨大な場合、数秒かかることがあります。</translation> + </message> + <message> <source>Received</source> <translation>受取</translation> </message> @@ -1524,6 +1515,10 @@ Address: %4 <translation>Ping時間</translation> </message> <message> + <source>Time Offset</source> + <translation>時間オフセット</translation> + </message> + <message> <source>Last block time</source> <translation>最終ブロックの日時</translation> </message> @@ -1564,16 +1559,12 @@ Address: %4 <translation>デバッグ用ログファイル</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>現在のデータ ディレクトリから Bitcoin のデバッグ用ログファイルを開きます。ログファイルが大規模な場合には数秒かかることがあります。</translation> - </message> - <message> <source>Clear console</source> <translation>コンソールをクリア</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Bitcoin RPC コンソールへようこそ。</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Bitcoin CoreのRPCコンソールへようこそ。</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1864,14 +1855,6 @@ Address: %4 <translation>手数料設定を折りたたむ</translation> </message> <message> - <source>Minimize</source> - <translation>最小化</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>カスタム手数料が1000satoshiに設定されている場合、トランザクションサイズが250バイトとすると、「1キロバイトあたり手数料」では250satoshiの手数料のみを支払いますが、「最小手数料」では1000satoshiを支払います。1キロバイトを超えるトランザクションの場合には、どちらの方法を選択したとしても1キロバイトあたりで支払われます。</translation> - </message> - <message> <source>per kilobyte</source> <translation>1キロバイトあたり手数料</translation> </message> @@ -1880,6 +1863,10 @@ Address: %4 <translation>カスタム手数料が1000satoshiに設定されている場合、トランザクションサイズが250バイトとすると、「1キロバイトあたり手数料」では250satoshiの手数料のみを支払いますが、「最小手数料」では1000satoshiを支払います。1キロバイトを超えるトランザクションの場合には、どちらの方法を選択したとしても1キロバイトあたりで支払われます。</translation> </message> <message> + <source>Hide</source> + <translation>隠す</translation> + </message> + <message> <source>total at least</source> <translation>最小手数料</translation> </message> @@ -2000,10 +1987,6 @@ Address: %4 <translation>または</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>受取人のアドレスが不正です。再確認してください。</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>支払額は0より大きくないといけません。</translation> </message> @@ -2016,10 +1999,6 @@ Address: %4 <translation>%1 の取引手数料を含めると額が残高を超えています。</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>重複しているアドレスが見つかりました。1回の送信で同じアドレスに送ることは出来ません。</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>トラザクションの作成に失敗しました!</translation> </message> @@ -2028,16 +2007,28 @@ Address: %4 <translation>トランザクションは拒否されました。wallet.dat のコピーを使い、そしてコピーしたウォレットからコインを使用したことがマークされなかったときなど、ウォレットのいくつかのコインがすでに使用されている場合に、このエラーは起こるかもしれません。</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> - <translation>%1 よりも高い手数料は、異常に高い手数料だと考えられます。</translation> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>%1 よりも高い手数料の場合、手数料が高すぎると判断されます。</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>支払いリクエストの期限が切れました。</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>%n ブロック以内に検証が開始されると予想されます。</numerusform></translation> </message> <message> <source>Pay only the minimum fee of %1</source> <translation>最小手数料 %1 のみを支払う</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>%1 ブロック以内に検証が終わると予想されます。</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>受取アドレスが不正です。再チェックしてください。</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>重複したアドレスが見つかりました: アドレスはそれぞれ一度のみ使用することができます。</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2111,12 +2102,24 @@ Address: %4 <translation>この項目を削除する</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>送金する金額から手数料が差し引かれます。受取人は数量フィールドで指定した量よりも少ないビットコインを受け取ります。受取人が複数いる場合には、手数料は均等割されます。</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>送金額から手数料を差し引く (&U)</translation> + </message> + <message> <source>Message:</source> <translation>メッセージ:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>これは検証済みの支払リクエストです。</translation> + <source>This is an unauthenticated payment request.</source> + <translation>これは未認証の支払いリクエストです。</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>これは認証済みの支払いリクエストです。</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2127,10 +2130,6 @@ Address: %4 <translation>bitcoin: URIに添付されていたメッセージです。これは参照用としてトランザクションとともに保存されます。注意:このメッセージはBitcoinネットワークを通して送信されるわけではありません。</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>これは未検証の支払リクエストです。</translation> - </message> - <message> <source>Pay To:</source> <translation>支払先:</translation> </message> @@ -2161,8 +2160,8 @@ Address: %4 <translation>メッセージの署名 (&S)</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>あなた自身を立証するためにあなたのアドレスでメッセージに署名することができます。フィッシング攻撃によってあなたを騙して署名を譲渡させようとするかもしれないので、不明確なものは絶対に署名しないように注意してください。あなたが同意する完全に詳細な声明にだけ署名してください。</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>あなたの所有しているアドレスによりメッセージや合意書に署名をすることで、それらアドレスに対して送られたビットコインを受け取ることができることを証明できます。フィッシング攻撃により不正にあなたの識別情報を署名させられてしまうことを防ぐために、不明確なものやランダムなものに対して署名しないよう注意してください。合意することが可能な、よく詳細の記された文言にのみ署名するようにしてください。</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2217,8 +2216,8 @@ Address: %4 <translation>メッセージの検証 (&V)</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>メッセージを検証するために、署名するアドレスとメッセージ(改行、スペース、タブなどを正確にコピーしてください)、そして署名を入力します。中間者攻撃によってだまされることを避けるために、署名されたメッセージそのものよりも、署名を読み取られないように注意してください。</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>受取人のアドレスとメッセージ(改行やスペース、タブなども完全に一致するよう注意してください)および署名を以下に入力し、メッセージの署名を検証してください。中間者攻撃により騙されるのを防ぐため、署名対象のメッセージに書かれていること以上の意味を署名から読み取ろうとしないよう注意してください。これは署名作成者がこのアドレスで受け取ったことを証明するだけであり、トランザクションの送信権限を証明するものではないことに注意してください!</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2484,10 +2483,6 @@ Address: %4 <translation>タイプ</translation> </message> <message> - <source>Address</source> - <translation>Helbidea</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>未成熟(%1検証。%2検証完了後に使用可能となります)</translation> </message> @@ -2516,6 +2511,10 @@ Address: %4 <translation>オフライン</translation> </message> <message> + <source>Label</source> + <translation>ラベル</translation> + </message> + <message> <source>Unconfirmed</source> <translation>未検証</translation> </message> @@ -2572,8 +2571,8 @@ Address: %4 <translation>監視限定アドレスがこのトランザクションに含まれているかどうか</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>取引の宛先アドレス。</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>ユーザ定義のトランザクションの意図や目的。</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2826,16 +2825,16 @@ Address: %4 <translation>MITソフトウェアライセンスのもとで配布されています。付属のCOPYINGファイルまたは<http://www.opensource.org/licenses/mit-license.php>を参照してください。</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>ブロックを瞬時に解決することができる特別なチェーンを使用して、リグレッションテストモードに入る。</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>ウォレットの取引を変更する際にコマンドを実行 (cmd の %s は TxID に置換される)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>このモードでは -genproclimit は何個のブロックをただちに生成するのか制御します。</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>ひとつのウォレットトランザクションで使用する合計手数料の最大値。低すぎる値を指定すると巨大なトランザクションの作成ができなくなります (規定値: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>古いブロックを剪定する(削除する)ことで記憶容量の必要量を削減する。このモードを有効にするとウォレット機能のサポートは無効になり、-txindexとも互換性がなくなります。警告: この設定の再有効化には全ブロックチェインの再ダウンロードが必要となります。(規定値: 0 = ブロックの剪定無効、>%u = ブロックファイルに使用するMiB単位の目標サイズ)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2850,6 +2849,14 @@ Address: %4 <translation>このコンピュータの %s にバインドすることができません。おそらく Bitcoin Core は既に実行されています。</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>警告:異常に多くの数のブロックが生成されています。%d ブロックが最近 %d 時間以内に受け取られました。(期待値: %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>警告:ネットワーク接続を確認してください。%d ブロックが最近 %d 時間以内にに受け取られました。(期待値: %d)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>警告: -paytxfee が非常に高く設定されています! これは取引を送信する場合に支払う取引手数料です。</translation> </message> @@ -2907,10 +2914,6 @@ Address: %4 <translation>デバッグ/テスト用オプション:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>自分の IP アドレスを発見 (初期値: リスン中と -externalip を使用していない場合は1)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>ウォレットは読み込まず、ウォレットRPCコールを無効化する</translation> </message> @@ -2971,8 +2974,12 @@ Address: %4 <translation><net> (ipv4, ipv6 または onion) ネットワーク内のノードだけに接続する</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>現在の blk000??.dat ファイルからブロック チェーンのインデックスを再構築</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>剪定値は負の値に設定できません。</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>剪定モードは-txindexと互換性がありません。</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2987,10 +2994,6 @@ Address: %4 <translation>ウォレットのファイルを指定 (データ・ディレクトリの中に)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>これはリグレッションテストツールやアプリ開発のためのものです。</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>リッスンポートの割当に UPnP を使用 (初期値: %u)</translation> </message> @@ -3011,6 +3014,10 @@ Address: %4 <translation>ウォレットオプション:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>警告: このバージョンはサポートされません。アップグレードが必要です!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>-txindex を変更するには -reindex を使用してデータベースを再構築する必要があります</translation> </message> @@ -3039,14 +3046,14 @@ Address: %4 <translation>データ ディレクトリ %s のロックを取得することができません。おそらく Bitcoin Core は実行中です。</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>手数料ゼロのトランザクションのリレー速度を一分間あたり <n>*1000 バイトに常に制限する (初期値: %u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>umask 077 ではなく、システムのデフォルトパーミッションで新規ファイルを作成する (ウォレット機能が無効化されていた場合にのみ有効)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>自分のIPアドレスを解決する (規定値: リッスンをしており、-externalipまたは-proxyオプションが指定されていない場合は1)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>エラー: 内向きの接続をリッスンするのに失敗しました (エラー %s が返却されました)</translation> </message> @@ -3063,10 +3070,6 @@ Address: %4 <translation>中継の際、この値未満の手数料 (BTC/Kb単位) はゼロであるとみなす (デフォルト: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>トランザクション作成の際、この値未満の手数料 (BTC/Kb単位) はゼロであるとみなす (デフォルト: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>paytxfee が設定されていなかった場合、平均して n ブロック以内にトランザクションが検証され始めるのに十分な手数料を含める (初期値: %u)</translation> </message> @@ -3079,16 +3082,16 @@ Address: %4 <translation>中継および採掘を行う際の、データ運送トランザクションの中のデータの最大サイズ (初期値: %u)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>ひとつのウォレットトランザクションで使用する合計手数料の最大値。低く設定し過ぎると大きなトランザクションの生成に失敗することがあります (初期値: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>剪定が最小値の %d MB以下に設定されています。もっと大きな値を使用してください。</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>保有するピアアドレスが少ない場合、DNS ルックアップによりピアアドレスを問い合わせる (-connect を使っていない場合の初期値: 1)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>手数料なし、または低手数料のトランザクションのリレー時に高い優先度を要求する (初期値: %u)</translation> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>認証情報をプロキシー接続ごとにランダム化する。これによりTorストリーム分離をすることができます (規定値: %u)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3099,6 +3102,10 @@ Address: %4 <translation>コイン生成が有効になっていた場合の利用スレッド数を設定する (-1 = すべてのコア, 初期値: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>手数料差引後のトランザクションの金額が小さすぎるため、送金できません。</translation> + </message> + <message> <source>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.</source> <translation>この製品はOpenSSLプロジェクトにより開発されたソフトウェアをOpenSSLツールキットとして利用しています <https://www.openssl.org/>。また、Eric Young氏により開発された暗号ソフトウェア、Thomas Bernard氏により書かれたUPnPソフトウェアを用いています。</translation> </message> @@ -3139,14 +3146,34 @@ rpcpassword=%s <translation>ホワイトリストのピアはDoSによるアクセス禁止処理が無効化され、トランザクションは例えmempool内に既に存在していたとしても常にリレーされます。これは例えばゲートウェイに対して有用です</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>非剪定モードに戻るためには-reindexオプションを使用してデータベースを再構築する必要があります。これによりブロックチェイン全体の再ダウンロードが行われます。</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(規定値: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>公開 REST リクエストを許可する (初期値: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>最優良のチェインを有効化しています...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>剪定モードではウォレット機能付きで起動できません。</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>-whitebind アドレス '%s' を解決できません</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>起動時にデータ ディレクトリを選ぶ (初期値: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>SOCKS5 プロキシ経由で接続する</translation> </message> @@ -3227,12 +3254,12 @@ rpcpassword=%s <translation>RPCにおけるHTTPの持続的接続のサポート (初期値: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation><n> 個のネットワークメッセージごとにひとつをランダムに捨てる</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>起動時に現在の blk000??.dat ファイルからブロック チェーンのインデックスを再構築</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation><n>個のネットワークメッセージごとにひとつをランダムに改変する</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>P2Pネットワークのアラートの受け取りと表示を行う (デフォルト: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3243,10 +3270,22 @@ rpcpassword=%s <translation>可能な場合には手数料ゼロのトランザクションとしてトランザクションを送信する (初期値: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>支払いリクエスト用にSSLルート証明書を設定する(デフォルト:-system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>言語設定 例: "de_DE" (初期値: システムの言語)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>すべてのデバッグオプションを表示する (使い方: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>起動時にスプラッシュ画面を表示する (初期値: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>クライアント起動時に debug.log ファイルを縮小 (初期値: -debug オプションを指定しない場合は1)</translation> </message> @@ -3255,6 +3294,14 @@ rpcpassword=%s <translation>取引の署名に失敗しました</translation> </message> <message> + <source>Start minimized</source> + <translation>最小化された状態で起動する</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>トランザクションの金額が小さすぎて手数料を支払えません</translation> + </message> + <message> <source>This is experimental software.</source> <translation>これは実験的なソフトウェアです。</translation> </message> @@ -3275,6 +3322,10 @@ rpcpassword=%s <translation>取引が大き過ぎます</translation> </message> <message> + <source>UI Options:</source> + <translation>UIオプション:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>このコンピュータの %s にバインドすることができません (バインドが返したエラーは %s)</translation> </message> @@ -3295,10 +3346,6 @@ rpcpassword=%s <translation>警告</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>警告: このバージョンは古いのでアップグレードが必要です!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>警告: サポートされていない引数 -benchmark は無視されました。-debug=bench を使用してください。</translation> </message> @@ -3359,18 +3406,10 @@ rpcpassword=%s <translation>(1 = トランザクションのメタデータ、例えばアカウントの所有者や支払リクエストの内容を保持する, 2 = トランザクションのメタデータを破棄する)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation><n> メガバイトごとにメモリプールからデータベースのアクティビティをディスクログに書き出す (初期値: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>-checkblocks のブロックの検証レベル (0-4, 初期値: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>ブロックの採掘時にトランザクションの優先度と1kBあたりの手数料をログに残す (デフォルト: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>getrawtransaction rpc 呼び出し時に用いる、完全なトランザクションインデックスを保持する (初期値: %u)</translation> </message> @@ -3399,18 +3438,10 @@ rpcpassword=%s <translation>DNS ルックアップを通してピアアドレスを常に問い合わせる (初期値: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>セーフモードを無効化し、実際のセーフモードイベントも無効化する (初期値: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>wallet.dat 読み込みエラー</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>セーフモードを強制する (初期値: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>コインを生成 (初期値: %u)</translation> </message> @@ -3427,10 +3458,6 @@ rpcpassword=%s <translation>無効な -proxy アドレス: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>署名キャッシュのサイズを <n> エントリーに制限する (デフォルト: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation><port> で JSON-RPC 接続をリスン (初期値: %u、testnet は %u)</translation> </message> @@ -3443,6 +3470,10 @@ rpcpassword=%s <translation>ピアの接続数を最大でも <n> 個に維持する (初期値: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>ウォレットのトランザクションをブロードキャストする</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>接続毎の最大受信バッファ <n>*1000 バイト (初期値: %u)</translation> </message> @@ -3451,10 +3482,6 @@ rpcpassword=%s <translation>接続毎の最大送信バッファ <n>*1000 バイト (初期値: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>内蔵のチェックポイントと一致するブロック チェーンのみを許可 (初期値: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>デバッグ出力にタイムスタンプを付ける (初期値: %u)</translation> </message> @@ -3467,10 +3494,6 @@ rpcpassword=%s <translation>P2SHでないマルチシグトランザクションをリレーする (初期値: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>ウォレットを定期的に書き出すためのスレッドを走らせる (初期値: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>サーバ証明書ファイル (初期値: %s)</translation> </message> @@ -3491,10 +3514,6 @@ rpcpassword=%s <translation>RPC サービスのスレッド数を設定 (初期値: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>ウォレットDB環境内にDB_PRIVATEフラグを設定する (デフォルト: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>設定ファイルの指定 (初期値: %s)</translation> </message> @@ -3511,10 +3530,6 @@ rpcpassword=%s <translation>トランザクション送信時に未検証のおつりを使用する (デフォルト: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>ディスクからブロックを読み込んだ後に終了する (デフォルト: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>不正なピアを切断するためのしきい値 (初期値: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts index 732081efda..4c6ce13eff 100644 --- a/src/qt/locale/bitcoin_ka.ts +++ b/src/qt/locale/bitcoin_ka.ts @@ -1,4 +1,4 @@ -<TS language="ka" version="2.1"> +<TS language="ka" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -148,10 +148,6 @@ <translation>ფრაზა-პაროლის შეცვლა</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>შეიყვანეთ საფულის ძველი და ახალი ფრაზა-პაროლი.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>დაადასტურეთ საფულის დაშიფრვა</translation> </message> @@ -176,10 +172,6 @@ <translation>საფულე დაშიფრულია</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>ახლა Bitcoin დაიხურება დაშიფრვის პროცესის დასასრულებლად. გაითვალისწინეთ, რომ დაშიფრვა სრულად ვერ დაიცავს თქვენს ბითქოინებს თქვენს კომპიუტერში შემოპარული მავნე პროგრამების საშუალებით დატაცებისაგან.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>ვერ მოხერხდა საფულის დაშიფრვა</translation> </message> @@ -295,10 +287,6 @@ <translation>მონეტების გაგზავნა Bitcoin-მისამართზე</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Bitcoin-ის საკონფიგურაციო პარამეტრების ცვლილება</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>საფულის არქივირება სხვა ადგილზე</translation> </message> @@ -451,18 +439,6 @@ <translation>მიღებული ტრანსაქციები</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>თარიღი: %1 -თანხა: %2 -ტიპი: %3 -მისამართი: %4 -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>საფულე <b>დაშიფრულია</b> და ამჟამად <b>განბლოკილია</b></translation> </message> @@ -641,10 +617,6 @@ Address: %4 <translation>არა</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>ნიშნული წითლდება, როცა ტრანსაქციის ზომა 1000 ბაიტზე მეტია.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>ეს ნიშნავს, რომ კილობაიტზე საკომისიო იქნება მინიმუმ %1</translation> </message> @@ -657,14 +629,6 @@ Address: %4 <translation>მეტი პრიორიტეტის ტრანსაქციებს მეტი შანსი აქვს მოხვდეს ბლოკში.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>ნიშნული წითლდება, როცა პრიორიტეტი "საშუალო"-ზე დაბალია.</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>ნიშნული წითლდება, როცა რომელიმე რეციპიენტი მიიღებს %1-ზე ნაკლებს.</translation> - </message> - <message> <source>(no label)</source> <translation>(არ არის ნიშნული)</translation> </message> @@ -781,26 +745,6 @@ Address: %4 <source>command-line options</source> <translation>კომანდების ზოლის ოპციები</translation> </message> - <message> - <source>UI options</source> - <translation>ინტერფეისის პარამეტრები</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>აირჩიეთ ენა, მაგალითად "de_DE" (ნაგულისხმევია სისტემური ლოკალი)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>გაშვება მინიმიზებული ეკრანით</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>მისალმების ეკრანის ჩვენება გაშვებისას (ნაგულისხმევი:1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>მონაცემთა კატალოგის მითითება ყოველი გაშვებისას (ნაგულისხმევი: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -867,14 +811,6 @@ Address: %4 <translation>&მთავარი</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>სისტემაში შესვლის შემდეგ Bitcoin-ის ავტომატური გაშვება.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&სისტემაში შესვლისას გაშვება</translation> - </message> - <message> <source>Size of &database cache</source> <translation>მონაცემთა ბაზის კეშის სი&დიდე</translation> </message> @@ -947,10 +883,6 @@ Address: %4 <translation>&მინიმიზება სისტემურ ზონაში პროგრამების პანელის ნაცვლად</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>პროგრამის მინიმიზება ფანჯრის დახურვისას. ოპციის ჩართვის შემდეგ პროგრამის დახურვა შესაძლებელი იქნება მხოლოდ მენიუდან - პუნქტი "გასვლა".</translation> - </message> - <message> <source>M&inimize on close</source> <translation>მ&ინიმიზება დახურვისას</translation> </message> @@ -963,10 +895,6 @@ Address: %4 <translation>სამომხმარებ&ლო ენა:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>აქ შეგიძლიათ აირჩიოთ სამომხმარებლო ენა. ძალაში შევა Bitcoin-ის რესტარტის შემდეგ.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>ერთეუ&ლი:</translation> </message> @@ -1003,10 +931,6 @@ Address: %4 <translation>ცვლილებები ძალაში შევა კლიენტის ხელახალი გაშვების შემდეგ.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>კლიენტი დაიხურება, გავაგრძელოთ?</translation> - </message> - <message> <source>This change would require a client restart.</source> <translation>ამ ცვლილებების ძალაში შესასვლელად საჭიროა კლიენტის დახურვა და ხელახალი გაშვება.</translation> </message> @@ -1057,11 +981,7 @@ Address: %4 <source>Your current total balance</source> <translation>თქვენი სრული მიმდინარე ბალანსი</translation> </message> - <message> - <source>out of sync</source> - <translation>არ არის სინქრონიზებული</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> <message> @@ -1253,18 +1173,10 @@ Address: %4 <translation>დახვეწის ლოგ-ფაილი</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>გახსენით Bitcoin-ის დახვეწის ლოგ-ფაილი მიმდინარე კატალოგიდან. დიდი ლოგ-ფაილის შემთხვევაში ამას შეიძლება რამდენიმე წამი მოუნდეს.</translation> - </message> - <message> <source>Clear console</source> <translation>კონსოლის გასუფთავება</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>მოგესალმებათ Bitcoin-ის RPC კონსოლი.</translation> - </message> - <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>კლავიშები "ზევით" და "ქვევით" - ისტორიაში მოძრაობა, <b>Ctrl-L</b> - ეკრანის გასუფთავება.</translation> </message> @@ -1589,10 +1501,6 @@ Address: %4 <translation>ან</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>მიმღების მისამართი არასწორია, შეამოწმეთ.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>გადახდის მოცულობა 0-ზე მეტი უნდა იყოს</translation> </message> @@ -1601,10 +1509,6 @@ Address: %4 <translation>თანხა აღემატება თქვენს ბალანსს</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>მისამართები დუბლირებულია, დაშვებულია ერთ ჯერზე თითო მისამართზე ერთხელ გაგზავნა.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>შეცდომა ტრანსაქციის შექმნისას!</translation> </message> @@ -1680,10 +1584,6 @@ Address: %4 <translation>მესიჯი:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>ეს არის ვერიფიცირებული გადახდის მოთხოვნა.</translation> - </message> - <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>შეიყვანეთ ამ მისამართის ნიშნული გამოყენებული მისამართების სიაში დასამატებლად</translation> </message> @@ -1692,10 +1592,6 @@ Address: %4 <translation>მესიჯი, რომელიც თან ერთვის მონეტებს: URI, რომელიც შეინახება ტრანსაქციასთან ერთად თქვენთვის. შენიშვნა: მესიჯი არ გაყვება გადახდას ბითქოინის ქსელში.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>ეს არის არავერიფიცირებული გადახდის მოთხოვნა.</translation> - </message> - <message> <source>Pay To:</source> <translation>ადრესატი:</translation> </message> @@ -1726,10 +1622,6 @@ Address: %4 <translation>მე&სიჯის ხელმოწერა</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>ხელმოწერით თქვენ ადასტურებთ, რომ მესიჯი თქვენია. ფრთხილად - არ მოაწეროთ ხელი რაიმე საეჭვოს: ფიშინგური ხრიკებით შეიძლება ის თქვენს მესიჯად გაასაღონ. მოაწერეთ ხელი მხოლოდ იმას, რასაც ყველა წვრილმანში ეთანხმებით.</translation> - </message> - <message> <source>Choose previously used address</source> <translation>აირჩიეთ ადრე გამოყენებული მისამართი</translation> </message> @@ -1778,10 +1670,6 @@ Address: %4 <translation>მესიჯის &ვერიფიკაცია</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>შეიყვანეთ ხელმოწერის მისამართი, მესიჯი (დაუკვირდით, რომ ზუსტად იყოს კოპირებული სტრიქონის გადატანები, ჰარები, ტაბულაციები და სხვ) და ხელმოწერა მესიჯის ვერიფიკაციისათვის. მიაქციეთ ყურადღება, რომ რაიმე ზედმეტი არ გაგყვეთ კოპირებისას, რათა არ გახდეთ "man-in-the-middle" შეტევის ობიექტი.</translation> - </message> - <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>შეამოწმეთ, რომ მესიჯი ხელმოწერილია მითითებული Bitcoin-მისამართით</translation> </message> @@ -2017,10 +1905,6 @@ Address: %4 <translation>ტიპი</translation> </message> <message> - <source>Address</source> - <translation>მისამართი</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>არ არის მომწიფებული (%1 დასტური, საჭიროა სულ %2)</translation> </message> @@ -2045,6 +1929,10 @@ Address: %4 <translation>ოფლაინშია</translation> </message> <message> + <source>Label</source> + <translation>ნიშნული</translation> + </message> + <message> <source>Unconfirmed</source> <translation>დაუდასტურებელია</translation> </message> @@ -2093,10 +1981,6 @@ Address: %4 <translation>ტრანსაქციის ტიპი.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>ტრანსაქიის დანიშნულების მისამართი.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>ბალანსიდან მოხსნილი ან დამატებული თანხა.</translation> </message> @@ -2331,10 +2215,6 @@ Address: %4 <translation>მოცემულ მისამართზე მიჯაჭვა მუდმივად მასზე მიყურადებით. გამოიყენეთ [host]:port ფორმა IPv6-სათვის</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>გადასვლა რეგრესული ტესტირების რეჟიმში, რომელიც იყენებს სპეციალურ ჯაჭვს ბლოკების დაუყოვნებლივი პოვნის შესაძლებლობით.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>კომანდის შესრულება საფულის ტრანსაქციის ცვლილებისას (%s კომანდაში ჩანაცვლდება TxID-ით)</translation> </message> @@ -2383,10 +2263,6 @@ Address: %4 <translation>შენიშნულია ბლოკთა ბაზის დაზიანება</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>საკუთარი IP-მისამართის განსაზღვრა (ნაგულისხმევი: 1 თუ ჩართულია მიყურადება და არ გამოიყენება -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>არ ჩაიტვირთოს საფულე და აიკრძალოს საფულისადმი RPC-მიმართვები</translation> </message> @@ -2435,10 +2311,6 @@ Address: %4 <translation>არ არის საკმარისი ფაილ-დესკრიპტორები.</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>ბლოკთა ჯაჭვის ინდექსის ხელახლა აგება blk000??.dat ფაილიდან</translation> - </message> - <message> <source>Set maximum block size in bytes (default: %d)</source> <translation>ბლოკის მაქსიმალური ზომის განსაზღვრა ბაიტებში (ნადულისხმევი: %d)</translation> </message> @@ -2447,10 +2319,6 @@ Address: %4 <translation>მიუთითეთ საფულის ფაილი (კატალოგში)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>გამოიყენება რეგრესული ტესტირების ინსტრუმენტებისა და პროგრამების შემუშავებისას.</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>ბლოკების ვერიფიკაცია...</translation> </message> @@ -2483,6 +2351,10 @@ Address: %4 <translation>მაღალპრიორიტეტული/დაბალსაკომისიოიანი ტრანსაქციების მაქსიმალური ზომა ბაიტებში (ნაგულისხმევი: %d)</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>მონაცემთა კატალოგის მითითება ყოველი გაშვებისას (ნაგულისხმევი: 0)</translation> + </message> + <message> <source>Information</source> <translation>ინფორმაცია</translation> </message> @@ -2499,6 +2371,14 @@ Address: %4 <translation>ტრასირების/დახვეწის ინფოს გაგზავნა კონსოლზე debug.log ფაილის ნაცვლად</translation> </message> <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>აირჩიეთ ენა, მაგალითად "de_DE" (ნაგულისხმევია სისტემური ლოკალი)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>მისალმების ეკრანის ჩვენება გაშვებისას (ნაგულისხმევი:1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>debug.log ფაილის შეკუმშვა გაშვებისას (ნაგულისხმევია: 1 როცა არ აყენია -debug)</translation> </message> @@ -2507,6 +2387,10 @@ Address: %4 <translation>ტრანსაქციების ხელმოწერა ვერ მოხერხდა</translation> </message> <message> + <source>Start minimized</source> + <translation>გაშვება მინიმიზებული ეკრანით</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>ტრანსაქციების რაოდენობა ძალიან ცოტაა</translation> </message> @@ -2531,10 +2415,6 @@ Address: %4 <translation>გაფრთხილება</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>ყურადღება: ვერსია მოძველებულია, საჭიროა განახლება!</translation> - </message> - <message> <source>Zapping all transactions from wallet...</source> <translation>ტრანსაქციების ჩახსნა საფულიდან...</translation> </message> diff --git a/src/qt/locale/bitcoin_kk_KZ.ts b/src/qt/locale/bitcoin_kk_KZ.ts index 5e827caa44..5ee9040633 100644 --- a/src/qt/locale/bitcoin_kk_KZ.ts +++ b/src/qt/locale/bitcoin_kk_KZ.ts @@ -1,4 +1,4 @@ -<TS language="kk_KZ" version="2.1"> +<TS language="kk_KZ" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -373,8 +373,8 @@ <translation>Күні</translation> </message> <message> - <source>Address</source> - <translation>Адрес</translation> + <source>Label</source> + <translation>таңба</translation> </message> </context> <context> diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index 211f850c18..5126e53f8e 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -1,7 +1,11 @@ -<TS language="ko_KR" version="2.1"> +<TS language="ko_KR" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>지갑 주소나 이름을 수정하려면 우클릭하세요.</translation> + </message> + <message> <source>Create a new address</source> <translation>새 주소 만들기</translation> </message> @@ -89,7 +93,11 @@ <source>Exporting Failed</source> <translation>내보내기 실패</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>%1으로 주소 리스트를 저장하는 동안 오류가 발생했습니다. 다시 시도해주세요.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -148,10 +156,6 @@ <translation>암호 변경</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>지갑의 예전 암호와 새로운 암호를 입력</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>지갑의 암호화를 확정</translation> </message> @@ -176,10 +180,6 @@ <translation>지갑 암호화 완료</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>암호화 처리 과정을 끝내기 위해 비트코인을 종료합니다. 지갑 암호화는 컴퓨터로의 멀웨어 감염으로 인한 비트코인 도난을 완전히 방지할 수 없음을 기억하세요.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>지갑 암호화 실패</translation> </message> @@ -299,10 +299,6 @@ <translation>비트코인 주소로 코인 전송</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>비트코인 설정 옵션 수정</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>지갑을 다른장소에 백업</translation> </message> @@ -471,18 +467,6 @@ <translation>들어오고 있는 거래</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>날짜: %1 -거래액: %2 -형식: %3 -주소: %4 -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>지갑이 암호화 되었고 현재 차단해제 되었습니다</translation> </message> @@ -501,6 +485,10 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>코인 선택</translation> + </message> + <message> <source>Quantity:</source> <translation>수량:</translation> </message> @@ -661,10 +649,6 @@ Address: %4 <translation>아니요</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>만약 거래 양이 1000bytes 보다 크면 제목이 빨간색으로 변합니다</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>이 의미는 수수료가 최소한 %1 per 키로바이트 필요합니다</translation> </message> @@ -673,10 +657,6 @@ Address: %4 <translation>우선 순위가 높은 거래의 경우 블럭에 포함될 가능성이 더 많습니다.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>우선권이 중간보다 작으면 제목이 빨간색으로 변합니다. </translation> - </message> - <message> <source>(no label)</source> <translation>(표 없음)</translation> </message> @@ -789,30 +769,6 @@ Address: %4 <source>command-line options</source> <translation>명령줄 옵션</translation> </message> - <message> - <source>UI options</source> - <translation>UI 옵션</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>"de_DE"와 같이 언어를 설정하십시오 (기본값: 시스템 로캘)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>최소화 상태에서 시작</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>지불 요청을 위해 SSL 최상위 인증을 설정합니다. (기본값: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>시작시 시작 화면 표시 (기본값: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>파일목록을 선택하여 시작하시오(기본값: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -883,14 +839,6 @@ Address: %4 <translation>메인(&M)</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>시스템 로그인후에 비트코인을 자동으로 시작합니다.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>시스템 로그인시 비트코인 시작(&S)</translation> - </message> - <message> <source>Size of &database cache</source> <translation>데이터베이스 캐시 크기</translation> </message> @@ -959,6 +907,14 @@ Address: %4 <translation>사용중인 UPnP 포트 매핑(&U)</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>SOCKS5 프록시를 통해 비트코인 네트워크 연결</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>SOCKS5 프록시를 거쳐 연결합니다 (기본값 프록시):</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>프록시 IP(&I):</translation> </message> @@ -983,10 +939,6 @@ Address: %4 <translation>작업 표시줄 대신 트레이로 최소화(&M)</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>창을 닫으면 프로그램에서 나가지 않고 최소화합니다. 이 옵션을 활성화하면, 프로그램은 메뉴에서 나가기를 선택한 후에만 닫힙니다.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>닫을때 최소화(&I)</translation> </message> @@ -999,10 +951,6 @@ Address: %4 <translation>사용자 인터페이스 언어(&L):</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>사용자 인터페이스 언어를 여기서 설정할 수 있습니다. 이 설정은 비트코인을 다시 시작할때 적용됩니다.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>거래액을 표시할 단위(&U):</translation> </message> @@ -1039,10 +987,6 @@ Address: %4 <translation>변경 사항을 적용하기 위해서는 프로그램이 종료 후 재시작되어야 합니다.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>클라이언트가 종료됩니다, 계속 진행하시겠습니까?</translation> - </message> - <message> <source>This change would require a client restart.</source> <translation>이 변경 사항 적용을 위해 프로그램 재시작이 필요합니다. </translation> </message> @@ -1101,11 +1045,7 @@ Address: %4 <source>Your current balance in watch-only addresses</source> <translation>모니터링 지갑의 현재 잔액</translation> </message> - <message> - <source>out of sync</source> - <translation>동기화 필요</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> <message> @@ -1171,6 +1111,10 @@ Address: %4 <translation>거래량</translation> </message> <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>비트코인 주소를 입력하기 (예. %1)</translation> + </message> + <message> <source>N/A</source> <translation>없음</translation> </message> @@ -1289,18 +1233,10 @@ Address: %4 <translation>로그 파일 디버그</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>비트코인 디버그 로그파일을 현재 데이터 폴더에서 여십시요. 용량이 큰 로그 파일들은 몇 초가 걸릴 수 있습니다.</translation> - </message> - <message> <source>Clear console</source> <translation>콘솔 초기화</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>비트코인 RPC 콘솔에 오신걸 환영합니다</translation> - </message> - <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>기록을 찾아보려면 위 아래 화살표 키를, 화면을 지우려면 <b>Ctrl-L</b>키를 사용하십시오.</translation> </message> @@ -1597,10 +1533,6 @@ Address: %4 <translation>또는</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>수령인 주소가 정확하지 않습니다. 재확인 바랍니다</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>지불하는 금액은 0 보다 커야 합니다.</translation> </message> @@ -1613,10 +1545,6 @@ Address: %4 <translation>%1 의 거래수수료를 포함하면 잔고를 초과합니다.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>두개 이상의 주소입니다. 한번에 하나의 주소에만 작업할 수 있습니다.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>거래를 생성하는 것을 실패하였습니다</translation> </message> @@ -1692,10 +1620,6 @@ Address: %4 <translation>메시지:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>지급 확인요청입니다.</translation> - </message> - <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>사용된 주소 목록에 새 주소를 추가하기 위해 제목을 입력합니다. </translation> </message> @@ -1704,10 +1628,6 @@ Address: %4 <translation>비트코인에 첨부된 메시지: 참고용으로 거래와 함께 저장될 URI. 메모: 이 메시지는 비트코인 네트워크로 전송되지 않습니다.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>지급요청 미확인입니다</translation> - </message> - <message> <source>Pay To:</source> <translation>송금할 대상 : </translation> </message> @@ -1738,10 +1658,6 @@ Address: %4 <translation>메시지 서명(&S)</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>여러분 자신을 증명하기 위해 주소를 첨가하고 섬여할 수 있습니다. 피싱 공격으로 말미암아 여러분의 서명을 통해 속아 넘어가게 할 수 있으므로, 서명하지 않은 어떤 모호한 요소든 주의하십시오. 동의하는 완전 무결한 조항에만 서명하십시오.</translation> - </message> - <message> <source>Choose previously used address</source> <translation>이전에 사용한 주소를 선택하십시오</translation> </message> @@ -1790,10 +1706,6 @@ Address: %4 <translation>메시지 검증(&V)</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>메시지를 검증하기 위해 아래 칸에 각각 지갑 주소와 메시지, 전자서명을 입력하세요. (메시지 원본의 띄어쓰기, 들여쓰기, 행 나눔 등이 정확하게 입력되어야 하므로 원본을 복사해서 입력하세요) 이 기능은 메시지 검증이 주 목적이며, 네트워크 침입자에 의해 변조되지 않도록 전자서명 해독에 불필요한 시간을 소모하지 마세요. </translation> - </message> - <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>정확한 비트코인주소가 입력됬는지 메시지를 확인하시오</translation> </message> @@ -2029,10 +1941,6 @@ Address: %4 <translation>종류</translation> </message> <message> - <source>Address</source> - <translation>주소</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>충분히 숙성되지 않은 상태 (%1 승인, %2 후에 사용 가능합니다)</translation> </message> @@ -2057,6 +1965,10 @@ Address: %4 <translation>오프라인</translation> </message> <message> + <source>Label</source> + <translation>표</translation> + </message> + <message> <source>Unconfirmed</source> <translation>미확인</translation> </message> @@ -2105,10 +2017,6 @@ Address: %4 <translation>거래의 종류.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>거래가 도달할 주소</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>변경된 잔고.</translation> </message> @@ -2399,10 +2307,6 @@ Address: %4 <translation>디버그 및 테스트 설정</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>자신의 아이피 주소를 발견합니다 (기본값: 1 반응이 없거나 외부 아이피가 없을 때)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>지갑 불러오기를 하지마시오 또한 지갑 RPC 연결을 차단하십시오</translation> </message> @@ -2451,10 +2355,6 @@ Address: %4 <translation>사용 가능한 파일 디스크립터-File Descriptor-가 부족합니다. </translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>현재의 blk000??.dat 파일들로부터 블록체인 색인을 재구성합니다.</translation> - </message> - <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>데이터베이스 케시 크기를 메가바이트로 설정(%d 부터 %d, 기본값: %d)</translation> </message> @@ -2503,6 +2403,10 @@ Address: %4 <translation>최대 크기를 최우선으로 설정 / 바이트당 최소 수수료로 거래(기본값: %d)</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>파일목록을 선택하여 시작하시오(기본값: 0)</translation> + </message> + <message> <source>Information</source> <translation>정보</translation> </message> @@ -2523,18 +2427,26 @@ Address: %4 <translation>RPC 서버 설정</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>모든 네트워크 메시지 마다 무작위로 1이 떨어진다</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>추적오류 정보를 degug.log 자료로 보내는 대신 콘솔로 보내기</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>지불 요청을 위해 SSL 최상위 인증을 설정합니다. (기본값: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>"de_DE"와 같이 언어를 설정하십시오 (기본값: 시스템 로캘)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>모든 디버그 설정 보기(설정: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>시작시 시작 화면 표시 (기본값: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>클라이언트 시작시 debug.log 파일 비우기(기본값: 디버그 안할때 1)</translation> </message> @@ -2543,6 +2455,10 @@ Address: %4 <translation>거래를 서명하는것을 실패하였습니다.</translation> </message> <message> + <source>Start minimized</source> + <translation>최소화 상태에서 시작</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>거래량이 너무 적습니다</translation> </message> @@ -2567,10 +2483,6 @@ Address: %4 <translation>경고</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>경고: 이 버전이 오래되어 업그레이드가 필요합니다!</translation> - </message> - <message> <source>Zapping all transactions from wallet...</source> <translation>지갑의 모든거래내역 건너뛰기...</translation> </message> diff --git a/src/qt/locale/bitcoin_ky.ts b/src/qt/locale/bitcoin_ky.ts index 58ef2e89e2..442d7c5d52 100644 --- a/src/qt/locale/bitcoin_ky.ts +++ b/src/qt/locale/bitcoin_ky.ts @@ -1,4 +1,4 @@ -<TS language="ky" version="2.1"> +<TS language="ky" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -149,11 +149,7 @@ </context> <context> <name>OverviewPage</name> - <message> - <source>out of sync</source> - <translation>синхрондоштурулган эмес</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> </context> @@ -292,10 +288,6 @@ <source>Date</source> <translation>Дата</translation> </message> - <message> - <source>Address</source> - <translation>Дарек</translation> - </message> </context> <context> <name>TransactionView</name> diff --git a/src/qt/locale/bitcoin_la.ts b/src/qt/locale/bitcoin_la.ts index b0011f87af..b1a69c9a9e 100644 --- a/src/qt/locale/bitcoin_la.ts +++ b/src/qt/locale/bitcoin_la.ts @@ -1,4 +1,4 @@ -<TS language="la" version="2.1"> +<TS language="la" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -104,10 +104,6 @@ <translation>Muta tesseram</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Insero veterem novamque tesseram cassidili.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Confirma cifrationem cassidilis</translation> </message> @@ -132,10 +128,6 @@ <translation>Cassidile cifratum</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin iam desinet ut finiat actionem cifrandi. Memento cassidile cifrare non posse cuncte curare ne tui nummi clepantur ab malis programatibus in tuo computatro.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>Cassidile cifrare abortum est</translation> </message> @@ -235,10 +227,6 @@ <translation>Mitte nummos ad inscriptionem Bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Muta configurationis optiones pro Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Conserva cassidile in locum alium</translation> </message> @@ -314,26 +302,10 @@ <source>Bitcoin Core</source> <translation>Bitcoin Nucleus</translation> </message> - <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n activa conexio ad rete Bitcoin</numerusform><numerusform>%n activae conexiones ad rete Bitcoin</numerusform></translation> - </message> <message> <source>No block source available...</source> <translation>Nulla fons frustorum absens...</translation> </message> - <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n hora</numerusform><numerusform>%n horae</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n dies</numerusform><numerusform>%n dies</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n week(s)</source> - <translation><numerusform>%n hebdomas</numerusform><numerusform>%n hebdomades</numerusform></translation> - </message> <message> <source>%1 behind</source> <translation>%1 post</translation> @@ -375,18 +347,6 @@ <translation>Transactio incipiens</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Dies: %1 -Quantitas: %2 -Typus: %3 -Inscriptio: %4 -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Cassidile <b>cifratum</b> est et iam nunc <b>reseratum</b></translation> </message> @@ -513,23 +473,7 @@ Inscriptio: %4 <source>command-line options</source> <translation>Optiones mandati intiantis</translation> </message> - <message> - <source>UI options</source> - <translation>UI optiones</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Constitue linguam, exempli gratia "de_DE" (praedefinitum: lingua systematis)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Incipe minifactum ut icon</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Monstra principem imaginem ad initium (praedefinitum: 1)</translation> - </message> - </context> +</context> <context> <name>Intro</name> <message> @@ -555,14 +499,6 @@ Inscriptio: %4 <translation>&Princeps</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Pelle Bitcoin per se postquam in systema inire.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Pelle Bitcoin cum inire systema</translation> - </message> - <message> <source>Reset all client options to default.</source> <translation>Reconstitue omnes optiones clientis ad praedefinita.</translation> </message> @@ -607,10 +543,6 @@ Inscriptio: %4 <translation>&Minifac in tabellam systematis potius quam applicationum</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minifac potius quam exire applicatione quando fenestra clausa sit. Si haec optio activa est, applicatio clausa erit tantum postquam selegeris Exi in menu.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inifac ad claudendum</translation> </message> @@ -623,10 +555,6 @@ Inscriptio: %4 <translation>&Lingua monstranda utenti:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Lingua monstranda utenti hic constitui potest. Haec configuratio effectiva erit postquam Bitcoin iterum initiatum erit.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Unita qua quantitates monstrare:</translation> </message> @@ -673,11 +601,7 @@ Inscriptio: %4 <source>Mined balance that has not yet matured</source> <translation>Fossum pendendum quod nondum maturum est</translation> </message> - <message> - <source>out of sync</source> - <translation>non synchronizato</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> <message> @@ -773,18 +697,10 @@ Inscriptio: %4 <translation>Debug catalogi plica</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Aperi plicam catalogi de Bitcoin debug ex activo indice datorum. Hoc possit pauca secunda pro plicis magnis catalogi.</translation> - </message> - <message> <source>Clear console</source> <translation>Vacuefac terminale</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Bene ventio in terminale RPC de Bitcoin.</translation> - </message> - <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Utere sagittis sursum deorsumque ut per historiam naviges, et <b>Ctrl+L</b> ut scrinium vacuefacias.</translation> </message> @@ -901,10 +817,6 @@ Inscriptio: %4 <translation>Copia quantitatem</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Inscriptio accipientis non est valida, sodes reproba.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Oportet quantitatem ad pensandum maiorem quam 0 esse.</translation> </message> @@ -917,10 +829,6 @@ Inscriptio: %4 <translation>Quantitas est ultra quod habes cum merces transactionis %1 includitur.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Geminata inscriptio inventa, tantum posse mittere ad quamque inscriptionem semel singulare operatione.</translation> - </message> - <message> <source>(no label)</source> <translation>(nullus titulus)</translation> </message> @@ -949,7 +857,7 @@ Inscriptio: %4 </message> <message> <source>Paste address from clipboard</source> - <translation>Conglutina inscriptionem ex latibulo</translation> + <translation>Glutina inscriptionem ex latibulo</translation> </message> <message> <source>Alt+P</source> @@ -974,10 +882,6 @@ Inscriptio: %4 <translation>&Signa Nuntium</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Potes nuntios signare inscriptionibus tuis ut demonstres te eas possidere. Cautus es non amibiguum signare, quia impetus phiscatorum conentur te fallere ut signes identitatem tuam ad eos. Solas signa sententias cuncte descriptas quibus convenis.</translation> - </message> - <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1022,10 +926,6 @@ Inscriptio: %4 <translation>&Verifica Nuntium</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Insere inscriptionem signantem, nuntium (cura ut copias intermissiones linearum, spatia, tabs, et cetera exacte) et signationem infra ut nuntium verifices. Cautus esto ne magis legas in signationem quam in nuntio signato ipso est, ut vites falli ab impetu homo-in-medio.</translation> - </message> - <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>Verifica nuntium ut cures signatum esse cum specifica inscriptione Bitcoin</translation> </message> @@ -1126,10 +1026,6 @@ Inscriptio: %4 <source>Status</source> <translation>Status</translation> </message> - <message numerus="yes"> - <source>, broadcast through %n node(s)</source> - <translation><numerusform>, disseminatum per %n nodo</numerusform><numerusform>, disseminata per %n nodis</numerusform></translation> - </message> <message> <source>Date</source> <translation>Dies</translation> @@ -1162,10 +1058,6 @@ Inscriptio: %4 <source>Credit</source> <translation>Creditum</translation> </message> - <message numerus="yes"> - <source>matures in %n more block(s)</source> - <translation><numerusform>maturum erit in %n plure frusto</numerusform><numerusform>maturum erit in %n pluribus frustis</numerusform></translation> - </message> <message> <source>not accepted</source> <translation>non acceptum</translation> @@ -1249,14 +1141,6 @@ Inscriptio: %4 <translation>Typus</translation> </message> <message> - <source>Address</source> - <translation>Inscriptio</translation> - </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>Aperi pro %n plure frusto</numerusform><numerusform>Aperi pro %n pluribus frustis</numerusform></translation> - </message> - <message> <source>Open until %1</source> <translation>Apertum donec %1</translation> </message> @@ -1273,6 +1157,10 @@ Inscriptio: %4 <translation>Generatum sed non acceptum</translation> </message> <message> + <source>Label</source> + <translation>Titulus</translation> + </message> + <message> <source>Received with</source> <translation>Acceptum cum</translation> </message> @@ -1309,10 +1197,6 @@ Inscriptio: %4 <translation>Typus transactionis.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Inscriptio destinationis transactionis.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Quantitas remota ex pendendo aut addita ei.</translation> </message> @@ -1551,10 +1435,6 @@ Inscriptio: %4 <translation>Corruptum databasum frustorum invenitur</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Discooperi propriam inscriptionem IP (praedefinitum: 1 quando auscultans et nullum -externalip)</translation> - </message> - <message> <source>Do you want to rebuild the block database now?</source> <translation>Visne reficere databasum frustorum iam?</translation> </message> @@ -1587,10 +1467,6 @@ Inscriptio: %4 <translation>Inopia descriptorum plicarum.</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Restituere indicem catenae frustorum ex activis plicis blk000??.dat</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>Verificante frusta...</translation> </message> @@ -1619,6 +1495,14 @@ Inscriptio: %4 <translation>Mitte informationem vestigii/debug ad terminale potius quam plicam debug.log</translation> </message> <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Constitue linguam, exempli gratia "de_DE" (praedefinitum: lingua systematis)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Monstra principem imaginem ad initium (praedefinitum: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Diminue plicam debug.log ad initium clientis (praedefinitum: 1 nisi -debug)</translation> </message> @@ -1627,6 +1511,10 @@ Inscriptio: %4 <translation>Signandum transactionis abortum est</translation> </message> <message> + <source>Start minimized</source> + <translation>Incipe minifactum ut icon</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Magnitudo transactionis nimis parva</translation> </message> @@ -1651,10 +1539,6 @@ Inscriptio: %4 <translation>Monitio</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Monitio: Haec versio obsoleta est, progressio postulata!</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat corrupta, salvare abortum est</translation> </message> diff --git a/src/qt/locale/bitcoin_lt.ts b/src/qt/locale/bitcoin_lt.ts index a77ee9b529..4e468911dc 100644 --- a/src/qt/locale/bitcoin_lt.ts +++ b/src/qt/locale/bitcoin_lt.ts @@ -1,7 +1,11 @@ -<TS language="lt" version="2.1"> +<TS language="lt" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Spustelėkite dešinįjį klaviša norint keisti adresą arba etiketę</translation> + </message> + <message> <source>Create a new address</source> <translation>Sukurti naują adresą</translation> </message> @@ -26,6 +30,10 @@ <translation>&Kopijuoti adresą</translation> </message> <message> + <source>Delete the currently selected address from the list</source> + <translation>Ištrinti pasirinktą adresą iš sąrašo</translation> + </message> + <message> <source>&Export</source> <translation>&Eksportuoti</translation> </message> @@ -34,6 +42,10 @@ <translation>&Trinti</translation> </message> <message> + <source>Choose the address to send coins to</source> + <translation>Pasirinkite adresą kuriam siūsite monetas</translation> + </message> + <message> <source>C&hoose</source> <translation>P&asirinkti</translation> </message> @@ -59,7 +71,7 @@ </message> <message> <source>Comma separated file (*.csv)</source> - <translation>Kableliais išskirtas failas (*.csv)</translation> + <translation>Kableliais atskirtų duomenų failas (*.csv)</translation> </message> <message> <source>Exporting Failed</source> @@ -128,10 +140,6 @@ <translation>Pakeisti slaptafrazę</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Įveskite seną ir naują piniginės slaptafrazes.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Patvirtinkite piniginės užšifravimą</translation> </message> @@ -152,10 +160,6 @@ <translation>Piniginė užšifruota</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin dabar užsidarys šifravimo proceso pabaigai. Atminkite, kad piniginės šifravimas negali pilnai apsaugoti bitcoinų vagysčių kai tinkle esančios kenkėjiškos programos patenka į jūsų kompiuterį.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>Nepavyko užšifruoti piniginę</translation> </message> @@ -255,6 +259,10 @@ <translation>&Gaunami adresai...</translation> </message> <message> + <source>Open &URI...</source> + <translation>Atidaryti &URI...</translation> + </message> + <message> <source>Bitcoin Core client</source> <translation>Bitcoin Core klientas</translation> </message> @@ -271,10 +279,6 @@ <translation>Siųsti monetas Bitcoin adresui</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Keisti bitcoin konfigūracijos galimybes</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Daryti piniginės atsarginę kopiją</translation> </message> @@ -350,26 +354,6 @@ <source>&About Bitcoin Core</source> <translation>&Apie Bitcoin Core</translation> </message> - <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n Bitcoin tinklo aktyvus ryšys</numerusform><numerusform>%n Bitcoin tinklo aktyvūs ryšiai</numerusform><numerusform>%n Bitcoin tinklo aktyvūs ryšiai</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n valanda</numerusform><numerusform>%n valandos</numerusform><numerusform>%n valandų</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n diena</numerusform><numerusform>%n dienos</numerusform><numerusform>%n dienų</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n week(s)</source> - <translation><numerusform>%n savaitė</numerusform><numerusform>%n savaitės</numerusform><numerusform>%n savaičių</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n year(s)</source> - <translation><numerusform>%n metas</numerusform><numerusform>%n metai</numerusform><numerusform>%n metų</numerusform></translation> - </message> <message> <source>Error</source> <translation>Klaida</translation> @@ -399,17 +383,6 @@ <translation>Ateinantis sandoris</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Data: %1 -Suma: %2 -Tipas: %3 -Adresas: %4</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Piniginė <b>užšifruota</b> ir šiuo metu <b>atrakinta</b></translation> </message> @@ -428,6 +401,10 @@ Adresas: %4</translation> <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>Monetų pasirinkimas</translation> + </message> + <message> <source>Quantity:</source> <translation>Kiekis:</translation> </message> @@ -652,19 +629,7 @@ Adresas: %4</translation> <source>command-line options</source> <translation>komandinės eilutės parametrai</translation> </message> - <message> - <source>UI options</source> - <translation>Naudotoji sąsajos parametrai</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Nustatyti kalbą, pavyzdžiui "lt_LT" (numatyta: sistemos kalba)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Paleisti sumažintą</translation> - </message> - </context> +</context> <context> <name>Intro</name> <message> @@ -698,14 +663,6 @@ Adresas: %4</translation> <translation>&Pagrindinės</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Automatiškai paleisti Bitkoin programą įjungus sistemą.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Paleisti Bitcoin programą su window sistemos paleidimu</translation> - </message> - <message> <source>&Network</source> <translation>&Tinklas</translation> </message> @@ -742,10 +699,6 @@ Adresas: %4</translation> <translation>&M sumažinti langą bet ne užduočių juostą</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Uždarant langą neuždaryti programos. Kai ši parinktis įjungta, programa bus uždaryta tik pasirinkus meniu komandą Baigti.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>&Sumažinti uždarant</translation> </message> @@ -758,10 +711,6 @@ Adresas: %4</translation> <translation>Naudotojo sąsajos &kalba:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Čia gali būti nustatyta naudotojo sąsajos kalba. Šis nustatymas įsigalios iš naujo paleidus Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Vienetai, kuriais rodyti sumas:</translation> </message> @@ -786,6 +735,10 @@ Adresas: %4</translation> <translation>niekas</translation> </message> <message> + <source>Confirm options reset</source> + <translation>Patvirtinti nustatymų atstatymą</translation> + </message> + <message> <source>The supplied proxy address is invalid.</source> <translation>Nurodytas tarpinio serverio adresas negalioja.</translation> </message> @@ -797,6 +750,14 @@ Adresas: %4</translation> <translation>Forma</translation> </message> <message> + <source>Available:</source> + <translation>Galimi:</translation> + </message> + <message> + <source>Pending:</source> + <translation>Laukiantys:</translation> + </message> + <message> <source>Immature:</source> <translation>Nepribrendę:</translation> </message> @@ -808,11 +769,7 @@ Adresas: %4</translation> <source>Your current total balance</source> <translation>Jūsų balansas</translation> </message> - <message> - <source>out of sync</source> - <translation>nesinchronizuota</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> <message> @@ -820,6 +777,10 @@ Adresas: %4</translation> <translation>URI apdorojimas</translation> </message> <message> + <source>Payment request rejected</source> + <translation>Mokėjimo siuntimas atmestas</translation> + </message> + <message> <source>Network request error</source> <translation>Tinklo užklausos klaida</translation> </message> @@ -896,6 +857,26 @@ Adresas: %4</translation> <translation>Dabartinis blokų skaičius</translation> </message> <message> + <source>Received</source> + <translation>Gauta</translation> + </message> + <message> + <source>Direction</source> + <translation>Kryptis</translation> + </message> + <message> + <source>Version</source> + <translation>Versija</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Nusiųsti baitai</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Gauti baitai</translation> + </message> + <message> <source>Last block time</source> <translation>Paskutinio bloko laikas</translation> </message> @@ -924,10 +905,6 @@ Adresas: %4</translation> <translation>Išvalyti konsolę</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Sveiki atvykę į Bitcoin RPC konsolę.</translation> - </message> - <message> <source>%1 B</source> <translation>%1 B</translation> </message> @@ -943,6 +920,10 @@ Adresas: %4</translation> <source>%1 GB</source> <translation>%1 GB</translation> </message> + <message> + <source>never</source> + <translation>Niekada</translation> + </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -951,6 +932,10 @@ Adresas: %4</translation> <translation>Ž&ymė:</translation> </message> <message> + <source>Clear</source> + <translation>Išvalyti</translation> + </message> + <message> <source>Copy label</source> <translation>Kopijuoti žymę</translation> </message> @@ -1100,10 +1085,6 @@ Adresas: %4</translation> <translation>Kopijuoti pirmumą</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Negaliojantis gavėjo adresas. Patikrinkite.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Apmokėjimo suma turi būti didesnė nei 0.</translation> </message> @@ -1116,10 +1097,6 @@ Adresas: %4</translation> <translation>Jei pridedame sandorio mokestį %1 bendra suma viršija jūsų balansą.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Rastas adreso dublikatas.</translation> - </message> - <message> <source>(no label)</source> <translation>(nėra žymės)</translation> </message> @@ -1400,10 +1377,6 @@ Adresas: %4</translation> <translation>Tipas</translation> </message> <message> - <source>Address</source> - <translation>Adresas</translation> - </message> - <message> <source>Open until %1</source> <translation>Atidaryta iki %1</translation> </message> @@ -1420,6 +1393,10 @@ Adresas: %4</translation> <translation>Išgauta bet nepriimta</translation> </message> <message> + <source>Label</source> + <translation>Žymė</translation> + </message> + <message> <source>Received with</source> <translation>Gauta su</translation> </message> @@ -1429,7 +1406,7 @@ Adresas: %4</translation> </message> <message> <source>Sent to</source> - <translation>Siųsta </translation> + <translation>Išsiųsta</translation> </message> <message> <source>Payment to yourself</source> @@ -1456,10 +1433,6 @@ Adresas: %4</translation> <translation>Sandorio tipas.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Sandorio paskirties adresas</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Suma pridėta ar išskaičiuota iš balanso</translation> </message> @@ -1674,6 +1647,14 @@ Adresas: %4</translation> <translation>Siųsti atsekimo/derinimo info į konsolę vietoj debug.log failo</translation> </message> <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Nustatyti kalbą, pavyzdžiui "lt_LT" (numatyta: sistemos kalba)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Paleisti sumažintą</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Bandymas naudoti UPnP struktūra klausymosi prievadui (default: 1 when listening)</translation> </message> diff --git a/src/qt/locale/bitcoin_lv_LV.ts b/src/qt/locale/bitcoin_lv_LV.ts index bd25749ad9..23b846bd49 100644 --- a/src/qt/locale/bitcoin_lv_LV.ts +++ b/src/qt/locale/bitcoin_lv_LV.ts @@ -1,4 +1,4 @@ -<TS language="lv_LV" version="2.1"> +<TS language="lv_LV" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -140,10 +140,6 @@ <translation>Mainīt paroli</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Ierakstiet maciņa veco un jauno paroli.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Apstiprināt maciņa šifrēšanu</translation> </message> @@ -164,10 +160,6 @@ <translation>Maciņš nošifrēts</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin aizvērsies, lai pabeigtu šifrēšanu. Atcerieties, ka maciņa šifrēšana nevar pilnībā novērst bitkoinu zādzību, ko veic datorā ieviesušās kaitīgas programmas.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>Maciņa šifrēšana neizdevās</translation> </message> @@ -287,10 +279,6 @@ <translation>Nosūtīt bitkoinus uz Bitcoin adresi</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Mainīt Bitcoin konfigurācijas uzstādījumus</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Izveidot maciņa rezerves kopiju citur</translation> </message> @@ -386,34 +374,14 @@ <source>&Command-line options</source> <translation>&Komandrindas iespējas</translation> </message> - <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n aktīvu savienojumu ar Bitcoin tīklu</numerusform><numerusform>%n aktīvs savienojums ar Bitcoin tīklu</numerusform><numerusform>%n aktīvu savienojumu as Bitcoin tīklu</numerusform></translation> - </message> <message> <source>No block source available...</source> <translation>Nav pieejams neviens bloku avots...</translation> </message> - <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n stundas</numerusform><numerusform>%n stunda</numerusform><numerusform>%n stundas</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n dienas</numerusform><numerusform>%n diena</numerusform><numerusform>%n dienas</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n week(s)</source> - <translation><numerusform>%n nedēļas</numerusform><numerusform>%n nedēļa</numerusform><numerusform>%n nedēļas</numerusform></translation> - </message> <message> <source>%1 and %2</source> <translation>%1 un %2</translation> </message> - <message numerus="yes"> - <source>%n year(s)</source> - <translation><numerusform>%n gadi</numerusform><numerusform>%n gads</numerusform><numerusform>%n gadi</numerusform></translation> - </message> <message> <source>%1 behind</source> <translation>%1 aizmugurē</translation> @@ -451,18 +419,6 @@ <translation>Ienākoša transakcija</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Datums: %1 -Daudzums: %2 -Tips: %3 -Adrese: %4 -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Maciņš ir <b>šifrēts</b> un pašlaik <b>atslēgts</b></translation> </message> @@ -630,7 +586,7 @@ Adrese: %4 </message> <message> <source>none</source> - <translation>neviens</translation> + <translation>neviena</translation> </message> <message> <source>yes</source> @@ -745,23 +701,7 @@ Adrese: %4 <source>command-line options</source> <translation>komandrindas izvēles</translation> </message> - <message> - <source>UI options</source> - <translation>Lietotāja interfeisa izvēlnes</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Uzstādiet valodu, piemēram "de_DE" (pēc noklusēšanas: sistēmas lokāle)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Sākt minimizētu</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Uzsākot, parādīt programmas informācijas logu (pēc noklusēšanas: 1)</translation> - </message> - </context> +</context> <context> <name>Intro</name> <message> @@ -823,14 +763,6 @@ Adrese: %4 <translation>&Galvenais</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Automātiski sākt Bitcoin pēc pieteikšanās sistēmā.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Sākt Bitcoin reizē ar sistēmu</translation> - </message> - <message> <source>Size of &database cache</source> <translation>&Datubāzes kešatmiņas izmērs</translation> </message> @@ -915,10 +847,6 @@ Adrese: %4 <translation>&Minimizēt uz sistēmas tekni, nevis rīkjoslu</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Logu aizverot, minimizēt, nevis beigt darbu. Kad šī izvēlne iespējota, programma aizvērsies tikai pēc Beigt komandas izvēlnē.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimizēt aizverot</translation> </message> @@ -931,10 +859,6 @@ Adrese: %4 <translation>Lietotāja interfeiss un &valoda:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Šeit var iestatīt lietotāja valodu. Iestatījums aktivizēsies pēc Bitcoin pārstartēšanas.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Vienības, kurās attēlot daudzumus:</translation> </message> @@ -967,10 +891,6 @@ Adrese: %4 <translation>Apstiprināt iestatījumu atiestatīšanu</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Klients tiks izslēgts, vai vēlaties turpināt?</translation> - </message> - <message> <source>The supplied proxy address is invalid.</source> <translation>Norādītā starpniekservera adrese nav derīga.</translation> </message> @@ -1013,11 +933,7 @@ Adrese: %4 <source>Your current total balance</source> <translation>Jūsu kopējā tekošā bilance</translation> </message> - <message> - <source>out of sync</source> - <translation>nav sinhronizēts</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> <message> @@ -1189,10 +1105,6 @@ Adrese: %4 <translation>Notīrīt konsoli</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Laipni lūgti Bitcoin RPC konsolē.</translation> - </message> - <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Izmantojiet bultiņas uz augšu un leju, lai pārvietotos pa vēsturi, un <b>Ctrl-L</b> ekrāna notīrīšanai.</translation> </message> @@ -1370,7 +1282,7 @@ Adrese: %4 <name>SendCoinsDialog</name> <message> <source>Send Coins</source> - <translation>Sūtīt bitkoinus</translation> + <translation>Sūtīt Bitkoinus</translation> </message> <message> <source>Coin Control Features</source> @@ -1493,10 +1405,6 @@ Adrese: %4 <translation>vai</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Saņēmēja adrese ir nepareiza, lūdzu pārbaudi.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Nosūtāmajai summai jābūt lielākai par 0.</translation> </message> @@ -1509,10 +1417,6 @@ Adrese: %4 <translation>Kopsumma pārsniedz pieejamo, ja pieskaitīta %1 transakcijas maksa.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Atrastas divas vienādas adreses, vienā nosūtīšanas reizē uz katru adresi var sūtīt tikai vienreiz.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Transakcijas izveidošana neizdevās!</translation> </message> @@ -1580,14 +1484,6 @@ Adrese: %4 <translation>Ziņojums:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Šis ir pārbaudīts maksājuma pieprasījums.</translation> - </message> - <message> - <source>This is an unverified payment request.</source> - <translation>Šis ir nepārbaudīts maksājuma pieprasījums.</translation> - </message> - <message> <source>Pay To:</source> <translation>Maksāt:</translation> </message> @@ -1866,10 +1762,6 @@ Adrese: %4 <source>, has not been successfully broadcast yet</source> <translation>, vēl nav veiksmīgi izziņots</translation> </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>Atvērts vel %n blokus</numerusform><numerusform>Atvērts vel %n bloku</numerusform><numerusform>Atvērts vel %n blokus</numerusform></translation> - </message> <message> <source>unknown</source> <translation>nav zināms</translation> @@ -1897,14 +1789,6 @@ Adrese: %4 <translation>Tips</translation> </message> <message> - <source>Address</source> - <translation>Adrese</translation> - </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>Atvērts vel %n blokus</numerusform><numerusform>Atvērts vel %n bloku</numerusform><numerusform>Atvērts vel %n blokus</numerusform></translation> - </message> - <message> <source>Open until %1</source> <translation>Atvērts līdz %1</translation> </message> @@ -1925,6 +1809,10 @@ Adrese: %4 <translation>Bezsaitē</translation> </message> <message> + <source>Label</source> + <translation>Nosaukums</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Neapstiprināts</translation> </message> @@ -1969,10 +1857,6 @@ Adrese: %4 <translation>Transakcijas tips.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Transakcijas mērķa adrese.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Bilancei pievienotais vai atņemtais daudzums.</translation> </message> @@ -2267,10 +2151,22 @@ Adrese: %4 <translation>Debug/trace informāciju izvadīt konsolē, nevis debug.log failā</translation> </message> <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Uzstādiet valodu, piemēram "de_DE" (pēc noklusēšanas: sistēmas lokāle)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Uzsākot, parādīt programmas informācijas logu (pēc noklusēšanas: 1)</translation> + </message> + <message> <source>Signing transaction failed</source> <translation>Transakcijas parakstīšana neizdevās</translation> </message> <message> + <source>Start minimized</source> + <translation>Sākt minimizētu</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Transakcijas summa ir pārāk maza</translation> </message> @@ -2291,10 +2187,6 @@ Adrese: %4 <translation>Brīdinājums</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Brīdinājums: Šī versija ir novecojusi, nepieciešams atjauninājums!</translation> - </message> - <message> <source>on startup</source> <translation>startēšanas laikā</translation> </message> diff --git a/src/qt/locale/bitcoin_mn.ts b/src/qt/locale/bitcoin_mn.ts index 26dbc741cc..73793482d6 100644 --- a/src/qt/locale/bitcoin_mn.ts +++ b/src/qt/locale/bitcoin_mn.ts @@ -1,4 +1,4 @@ -<TS language="mn" version="2.1"> +<TS language="mn" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -6,18 +6,66 @@ <translation>Шинэ хаяг нээх</translation> </message> <message> + <source>&New</source> + <translation>&Шинэ</translation> + </message> + <message> <source>Copy the currently selected address to the system clipboard</source> <translation>Одоогоор сонгогдсон байгаа хаягуудыг сануулах</translation> </message> <message> + <source>&Copy</source> + <translation>&Хуулах</translation> + </message> + <message> + <source>C&lose</source> + <translation>&Хаах</translation> + </message> + <message> <source>&Copy Address</source> <translation>Хаягийг &Хуулбарлах</translation> </message> <message> + <source>Delete the currently selected address from the list</source> + <translation>Одоо сонгогдсон байгаа хаягуудыг жагсаалтаас устгах</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Сонгогдсон таб дээрхи дата-г экспортлох</translation> + </message> + <message> + <source>&Export</source> + <translation>&Экспортдлох</translation> + </message> + <message> <source>&Delete</source> <translation>&Устгах</translation> </message> <message> + <source>Choose the address to send coins to</source> + <translation>Зооснуудыг илгээх хаягийг сонгоно уу</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>Зооснуудыг хүлээн авах хаягийг сонгоно уу</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Илгээх хаягууд</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Хүлээн авах хаяг</translation> + </message> + <message> + <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> + <translation>Эдгээр Биткойн хаягууд нь илгээх хаягууд. Хүлээн авах хаяг болон тоо хэмжээг илгээхээсээ өмнө сайн нягталж үзэж байна уу</translation> + </message> + <message> + <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> + <translation>Эдгээр Биткойн хаягууд нь хүлээн авах хаягууд. Гүйлгээ болгонд шинээр хаяг үүсгэхийг бид санал болгож байна.</translation> + </message> + <message> <source>Copy &Label</source> <translation>&Шошгыг хуулбарлах</translation> </message> @@ -26,6 +74,10 @@ <translation>&Ѳѳрчлѳх</translation> </message> <message> + <source>Export Address List</source> + <translation>Экспорт хийх хаягуудын жагсаалт</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Таслалаар тусгаарлагдсан хүснэгтэн файл (.csv)</translation> </message> @@ -42,7 +94,7 @@ </message> <message> <source>(no label)</source> - <translation>(шошго алга)</translation> + <translation>(шошгогүй)</translation> </message> </context> <context> @@ -84,10 +136,6 @@ <translation>Нууц үгийг солих</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Түрүйвчийн хуучин болоод шинэ нууц үгсийг оруулна уу</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Түрүйвчийн цоожийг баталгаажуулах</translation> </message> @@ -96,10 +144,6 @@ <translation>Түрүйвч цоожлогдлоо</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Цоожлолтын процесыг дуусгахын тулд Биткойн одоо хаагдана. Ѳѳрийн түрүйвчийг цоожлох нь таны биткойнуудыг компьютерийн вирус хулгайлахаас бүрэн сэргийлж чадахгүй гэдгийг санаарай.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>Түрүйвчийн цоожлол амжилттай болсонгүй</translation> </message> @@ -214,18 +258,6 @@ <source>&Help</source> <translation>&Тусламж</translation> </message> - <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>Биткойны сүлжээрүү %n идэвхитэй холболт байна </numerusform><numerusform>Биткойны сүлжээрүү %n идэвхитэй холболтууд байна </numerusform></translation> - </message> - <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n цаг</numerusform><numerusform>%n цаг</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n ѳдѳр</numerusform><numerusform>%n ѳдрүүд</numerusform></translation> - </message> <message> <source>Error</source> <translation>Алдаа</translation> @@ -243,21 +275,6 @@ <translation>Дотогшоо гүйлгээ</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Огноо: %1 - -Хэмжээ: %2 - -Тѳрѳл: %3 - -Хаяг: %4 -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Түрүйвч <b>цоожтой</b> ба одоогоор цоож <b>онгорхой</b> байна</translation> </message> @@ -402,10 +419,6 @@ Address: %4 <translation>Ѳѳрчлѳлтүүдийг идэвхижүүлхийн тулд клиентийг ахин эхлүүлэх шаардлагтай</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Клиент унтрах гэж байна, яг унтраах уу?</translation> - </message> - <message> <source>This change would require a client restart.</source> <translation>Энэ ѳѳрчлѳлтийг оруулахын тулд кли1нт програмыг ахин эхлүүлэх шаардлагтай</translation> </message> @@ -570,7 +583,7 @@ Address: %4 </message> <message> <source>(no label)</source> - <translation>(шошго алга)</translation> + <translation>(шошгогүй)</translation> </message> <message> <source>(no message)</source> @@ -800,10 +813,6 @@ Address: %4 <translation>Тѳрѳл</translation> </message> <message> - <source>Address</source> - <translation>Хаяг</translation> - </message> - <message> <source>Open until %1</source> <translation>%1 хүртэл нээлттэй</translation> </message> @@ -820,6 +829,10 @@ Address: %4 <translation>Үүсгэгдсэн гэхдээ хүлээн авагдаагүй</translation> </message> <message> + <source>Label</source> + <translation>Шошго</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Баталгаажаагүй</translation> </message> @@ -864,10 +877,6 @@ Address: %4 <translation>Гүйлгээний тѳрѳл</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Гүйлгээг хүлээн авах хаяг</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Балансаас авагдсан болон нэмэгдсэн хэмжээ.</translation> </message> @@ -1002,6 +1011,14 @@ Address: %4 </context> <context> <name>WalletView</name> + <message> + <source>&Export</source> + <translation>&Экспортдлох</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Сонгогдсон таб дээрхи дата-г экспортлох</translation> + </message> </context> <context> <name>bitcoin-core</name> diff --git a/src/qt/locale/bitcoin_ms_MY.ts b/src/qt/locale/bitcoin_ms_MY.ts index e7a5a64f46..5e10c80aff 100644 --- a/src/qt/locale/bitcoin_ms_MY.ts +++ b/src/qt/locale/bitcoin_ms_MY.ts @@ -1,4 +1,4 @@ -<TS language="ms_MY" version="2.1"> +<TS language="ms_MY" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ </context> <context> <name>TransactionTableModel</name> - <message> - <source>Address</source> - <translation>Alamat</translation> - </message> </context> <context> <name>TransactionView</name> diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index eaaf8d7805..385f038d46 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -1,4 +1,4 @@ -<TS language="nb" version="2.1"> +<TS language="nb" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ <translation>Endre adgangsfrase</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Skriv inn gammel og ny adgangsfrase for lommeboken.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Bekreft kryptering av lommebok</translation> </message> @@ -172,6 +168,10 @@ <translation>Er du sikker på at du vil kryptere lommeboken?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -188,8 +188,8 @@ <translation>Oppgi adgangsfrasen til lommeboken.<br/>Vennligst bruk en adgangsfrase med <b>ti eller flere tilfeldige tegn</b>, eller <b>åtte eller flere ord</b>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin vil nå lukkes for å fullføre krypteringsprosessen. Husk at kryptering av lommeboken ikke fullt ut kan beskytte dine bitcoins fra å bli stjålet om skadevare infiserer datamaskinen.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Oppgi gammel og ny adgangsfrase til lommeboken.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>Send til en Bitcoin-adresse</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Endre oppsett for Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Sikkerhetskopier lommebok til annet sted</translation> </message> @@ -403,6 +399,10 @@ <translation>&Om Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Endre konfigurasjonsvalg for Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Vis listen av brukte utsendingsadresser og merkelapper</translation> </message> @@ -431,6 +431,10 @@ <translation>Ingen kilde for blokker tilgjengelig...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Lastet %n blokk med transaksjonshistorikk.</numerusform><numerusform>Lastet %n blokker med transaksjonshistorikk.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n time</numerusform><numerusform>%n timer</numerusform></translation> </message> @@ -478,35 +482,49 @@ <source>Up to date</source> <translation>Oppdatert</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>Lastet %n blokk med transaksjonshistorikk.</numerusform><numerusform>Lastet %n blokker med transaksjonshistorikk.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Laster ned...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Sendt transaksjon</translation> + <source>Date: %1 +</source> + <translation>Dato: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Innkommende transaksjon</translation> + <source>Amount: %1 +</source> + <translation>Beløp: %1: +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Dato: %1 -Beløp: %2 -Type: %3 -Adresse: %4 + <translation>Type: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Merkelapp: %1 </translation> </message> <message> + <source>Address: %1 +</source> + <translation>Adresse: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Sendt transaksjon</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Innkommende transaksjon</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Lommeboken er <b>kryptert</b> og for tiden <b>låst opp</b></translation> </message> @@ -697,6 +715,18 @@ Adresse: %4 <translation>ingen</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Denne teksten blir rød hvis transaksjonsstørrelsen er større enn 1000 bytes.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Denne teksten blir rød hvis prioriteten er lavere enn "medium".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Denne teksten blir rød dersom en mottaker mottar et beløp mindre enn %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Kan variere +/- %1 satoshi(er) per input.</translation> </message> @@ -709,10 +739,6 @@ Adresse: %4 <translation>nei</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Denne merkelappen blir rød, hvis transaksjonsstørrelsen er større enn 1000 bytes.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Dette betyr at et gebyr på minst %1 per KB er påkrevd.</translation> </message> @@ -725,14 +751,6 @@ Adresse: %4 <translation>Transaksjoner med høyere prioritet har mer sannsynlighet for å bli inkludert i en blokk.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Denne merkelappen blir rød, hvis prioriteten er mindre enn "medium".</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Denne merkelappen blir rød, hvis en mottaker mottar en mengde på mindre enn %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(ingen merkelapp)</translation> </message> @@ -853,30 +871,6 @@ Adresse: %4 <source>command-line options</source> <translation>kommandolinjevalg</translation> </message> - <message> - <source>UI options</source> - <translation>valg i brukergrensesnitt</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Sett språk, for eksempel "nb_NO" (standardverdi: fra operativsystem)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Start minimert</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Sett SSL-rotsertifikat for betalingsetterspørring (standard: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Vis splashskjerm ved oppstart (standardverdi: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Velg datamappe ved oppstart (standard: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -959,14 +953,6 @@ Adresse: %4 <translation>&Hoved</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Start Bitcoin automatisk etter innlogging.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Start Bitcoin ved systeminnlogging</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Størrelse på &database hurtigbuffer</translation> </message> @@ -991,6 +977,14 @@ Adresse: %4 <translation>IP-adressen til proxyen (f.eks. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Språk for brukergrensesnittet kan velges her. Denne innstillingen trer i kraft etter omstart av Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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 |.</translation> </message> @@ -1015,6 +1009,14 @@ Adresse: %4 <translation>&Nettverk</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Start Bitcoin Core automatisk ved oppstart av datamaskinen.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Start Bitcoin Core ved oppstart av datamaskinen</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = automatisk, <0 = la så mange kjerner være ledig)</translation> </message> @@ -1079,10 +1081,6 @@ Adresse: %4 <translation>&Minimer til systemkurv istedenfor oppgavelinjen</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimerer vinduet istedenfor å avslutte applikasjonen når vinduet lukkes. Når dette er slått på avsluttes applikasjonen kun ved å velge avslutt i menyen.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimer ved lukking</translation> </message> @@ -1095,10 +1093,6 @@ Adresse: %4 <translation>&Språk for brukergrensesnitt</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Språket for brukergrensesnittet kan settes her. Innstillingen trer i kraft ved omstart av Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Enhet for visning av beløper:</translation> </message> @@ -1135,8 +1129,8 @@ Adresse: %4 <translation>Omstart av klienten er nødvendig for å aktivere endringene.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Klienten vil bli lukket, vil du fortsette?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Klienten vil bli lukket. Ønsker du å gå videre?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1221,10 +1215,6 @@ Adresse: %4 <source>Current total balance in watch-only addresses</source> <translation>Nåværende totale balanse i kun observerbare adresser</translation> </message> - <message> - <source>out of sync</source> - <translation>ute av synk</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1245,10 +1235,6 @@ Adresse: %4 <translation>Nettverk for betalingsetterspørring er ikke i overensstemmelse med klientnettverket.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Betalingsetterspørringen har utløpt.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Betalingsetterspørringen er ikke initialisert.</translation> </message> @@ -1281,10 +1267,18 @@ Adresse: %4 <translation>Betalingsetterspørringsfil kan ikke leses! Dette kan være forårsaket av en ugyldig betalingsetterspørringsfil.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Betalingsetterspørringen har utløpt.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Uverifiserte betalingsforespørsler til egentilpassede betalingscript er ikke støttet.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Ugyldig betalingsetterspørring.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Refundering fra %1</translation> </message> @@ -1324,8 +1318,8 @@ Adresse: %4 <translation>Brukeragent</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Adresse/Vertsnavn</translation> + <source>Node/Service</source> + <translation>Node/Tjeneste</translation> </message> <message> <source>Ping Time</source> @@ -1359,14 +1353,6 @@ Adresse: %4 <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>NETTVERK</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>UKJENT</translation> - </message> - <message> <source>None</source> <translation>Ingen</translation> </message> @@ -1457,6 +1443,10 @@ Adresse: %4 <translation>Nåværende antall blokker</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Åpne Bitcoin Core sin loggfil for feilsøk fra gjeldende datamappe. Dette kan ta noen sekunder for store loggfiler.</translation> + </message> + <message> <source>Received</source> <translation>Mottatt</translation> </message> @@ -1525,6 +1515,10 @@ Adresse: %4 <translation>Ping-tid</translation> </message> <message> + <source>Time Offset</source> + <translation>Tidsforskyvning</translation> + </message> + <message> <source>Last block time</source> <translation>Tidspunkt for siste blokk</translation> </message> @@ -1565,16 +1559,12 @@ Adresse: %4 <translation>Loggfil for feilsøk</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Åpne Bitcoin sin loggfil for feilsøk fra den gjeldende datamappen. Dette kan ta noen sekunder for store loggfiler.</translation> - </message> - <message> <source>Clear console</source> <translation>Tøm konsoll</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Velkommen til Bitcoin sin RPC-konsoll.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Velkommen til Bitcoin Core sin RPC-konsoll.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1865,14 +1855,6 @@ Adresse: %4 <translation>Legg ned gebyrinnstillinger</translation> </message> <message> - <source>Minimize</source> - <translation>Minimer</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Hvis den egendefinerte avgiften er satt til 1000 satoshis og transaksjonen bare er 250 bytes, da vil "per kilobyte" bare betale 250 satoshis i gebyr, mens "minst" betaler 1000 satoshis. For transaksjoner større enn en kilobyte vil begge betale for antall kilobyte.</translation> - </message> - <message> <source>per kilobyte</source> <translation>per kilobyte</translation> </message> @@ -1881,6 +1863,10 @@ Adresse: %4 <translation>Hvis den egendefinerte avgiften er satt til 1000 satoshis og transaksjonen bare er 250 bytes, da vil "per kilobyte" bare betale 250 satoshis i gebyr, mens "minstebeløp" betaler 1000 satoshis. For transaksjoner større enn en kilobyte vil begge betale for antall kilobyte.</translation> </message> <message> + <source>Hide</source> + <translation>Skjul</translation> + </message> + <message> <source>total at least</source> <translation>minstebeløp</translation> </message> @@ -2001,10 +1987,6 @@ Adresse: %4 <translation>eller</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Adresse for mottaker er ugyldig.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Beløpet som skal betales må være over 0.</translation> </message> @@ -2017,10 +1999,6 @@ Adresse: %4 <translation>Totalbeløpet overstiger saldo etter at %1 transaksjonsgebyr er lagt til.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Doble antall adresser funnet. Kan bare sende en gang til hver adresse per operasjon.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Opprettelse av transaksjon feilet!</translation> </message> @@ -2029,16 +2007,28 @@ Adresse: %4 <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> - <translation>Et gebyr høyere enn %1 er ansett som et sinnsykt høyt gebyr.</translation> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Et gebyr høyere enn %1 er ansett som et absurd høyt gebyr.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Betalingsetterspørringen har utløpt.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Anslått til å begynne bekreftelse innen %n blokk.</numerusform><numerusform>Anslått til å begynne bekreftelse innen %n blokker.</numerusform></translation> </message> <message> <source>Pay only the minimum fee of %1</source> <translation>Betal kun minimumsgebyret på %1</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Beregner å begynne bekreftelse innen %1 blokk(er).</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Mottakeradressen er ikke gyldig. Vennligst kontroller på nytt.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Gjenbruk av adresse funnet: adresser skal bare brukes en gang hver.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2112,12 +2102,24 @@ Adresse: %4 <translation>Fjern denne oppføringen</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>Gebyret vil bli trukket fra beløpet som blir sendt. Mottakeren vil motta mindre bitcoins enn det du skriver inn i beløpsfeltet. Hvis det er valgt flere mottakere, deles gebyret likt.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>T&rekk fra gebyr fra beløp</translation> + </message> + <message> <source>Message:</source> <translation>Melding:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Dette er en verifisert betalingsetterspørring</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Dette er en uautorisert betalingsetterspørring.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Dette er en autorisert betalingsetterspørring.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2128,10 +2130,6 @@ Adresse: %4 <translation>En melding som var tilknyttet bitcoinen: URI vil bli lagret med transaksjonen for din oversikt. Denne meldingen vil ikke bli sendt over Bitcoin-nettverket.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Dette er en uverifisert betalingsetterspørring</translation> - </message> - <message> <source>Pay To:</source> <translation>Betal Til:</translation> </message> @@ -2162,8 +2160,8 @@ Adresse: %4 <translation>&Signer Melding</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Du kan signere meldinger med dine adresser for å bevise at du eier dem. Ikke signer vage meldinger da phishing-angrep kan prøve å lure deg til å signere din identitet over til andre. Signer kun fullt detaljerte utsagn som du er enig i.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Du kan signere meldinger/avtaler med adresser for å bevise at du kan motta bitcoins sendt til dem. Vær forsiktig med å signere noe vagt eller tilfeldig, siden phishing-angrep kan prøve å lure deg til å signere din identitet over til dem. Bare signer fullt detaljerte utsagn som du er enig i.</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2218,8 +2216,8 @@ Adresse: %4 <translation>&Verifiser Melding</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Angi adresse for signering, melding (vær sikker på at du kopierer linjeskift, mellomrom, tab, etc. helt nøyaktig) og signatur under for å verifisere meldingen. Vær forsiktig med at du ikke gir signaturen mer betydning enn det som faktisk står i meldingen, for å unngå å bli lurt av såkalte "man-in-the-middle" angrep.</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Skriv inn mottakerens adresse, melding (forsikre deg om at du kopier linjeskift, mellomrom, faner osv. nøyaktig) og underskrift nedenfor for å bekrefte meldingen. Vær forsiktig så du ikke leser mer ut av signaturen enn hva som er i den signerte meldingen i seg selv, for å unngå å bli lurt av et man-in-the-middle-angrep. Merk at dette bare beviser at den som signerer kan motta med adressen, dette beviser ikke hvem som har sendt transaksjoner!</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2485,10 +2483,6 @@ Adresse: %4 <translation>Type</translation> </message> <message> - <source>Address</source> - <translation>Adresse</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Umoden (%1 bekreftelser, vil være tilgjengelig etter %2)</translation> </message> @@ -2517,6 +2511,10 @@ Adresse: %4 <translation>Frakoblet</translation> </message> <message> + <source>Label</source> + <translation>Merkelapp</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Ubekreftet</translation> </message> @@ -2573,8 +2571,8 @@ Adresse: %4 <translation>Hvorvidt en kun observerbar adresse er involvert i denne transaksjonen.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Mottaksadresse for transaksjonen.</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Brukerdefinert intensjon/hensikt med transaksjonen.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2827,16 +2825,16 @@ Adresse: %4 <translation>Distribuert under MIT programvarelisensen, se medfølgende fil COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Gå til modus for regresjonstesting, som bruker en spesiell blokkjede der blokker kan bli løst momentant.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Kjør kommando når en lommeboktransaksjon endres (%s i kommando er erstattet med TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>I denne modusen kontrollerer -genproclimit hvor mange blokker som genereres øyeblikkelig.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Maksimalt samlede gebyrer til å bruke i en enkelt lommeboktransaksjon; settes dette for lavt kan store transaksjoner kanskje avbrytes (standardverdi: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Reduser lagringsbehovet ved beskjæring (slette) gamle blokker. Denne modusen deaktiverer støtte for lommebok og er ikke kompatibel med -txindex. Advarsel: Tilbakestilling av denne innstillingen krever at hele blokkjeden må lastes ned på nytt. (Standardverdi: 0 = deaktiver beskjæringsblokker, >%u = mål for størrelse i MiB å bruke for blokkfiler)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2851,6 +2849,14 @@ Adresse: %4 <translation>Ute av stand til å binde til %s på denne datamaskinen. Bitcoin Core kjører sannsynligvis allerede.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>ADVARSEL: unormalt høyt antall blokker generert, %d blokker mottatt de siste %d timene (%d forventet)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>ADVARSEL: kontroller nettverkstilkoblingen, mottok %d blokker i de siste %d timene (%d forventet)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Advarsel: -paytxfee er satt veldig høyt! Dette er transaksjonsgebyret du betaler når du sender transaksjoner.</translation> </message> @@ -2907,10 +2913,6 @@ Adresse: %4 <translation>Valg for feilsøking/testing:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Oppdag egen IP-adresse (standardverdi: 1 ved lytting og uten -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Ikke last inn lommeboken og deaktiver RPC-kall</translation> </message> @@ -2971,8 +2973,12 @@ Adresse: %4 <translation>Bare koble til noder i nettverket <net> (IPv4, IPv6 eller onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Gjenopprett blokkjedeindeks fra blk000??.dat filer</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>Beskjæringsmodus kan ikke konfigureres med en negativ verdi.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Beskjæringsmodus er ikke kompatibel med -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2987,10 +2993,6 @@ Adresse: %4 <translation>Angi lommebokfil (inne i datamappe)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Dette er tiltenkt verktøy for regresjonstesting og apputvikling.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Bruk UPnP for å sette opp lytteport (standardverdi: %u)</translation> </message> @@ -3011,6 +3013,10 @@ Adresse: %4 <translation>Valg for lommebok:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Advarsel: Denne versjonen er utdatert; oppgradering er påkrevd!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Du må gjenoppbygge databasen med å bruke -reindex for å endre -txindex</translation> </message> @@ -3039,14 +3045,14 @@ Adresse: %4 <translation>Ute av stand til å låse datamappen %s. Bitcoin Core kjører sannsynligvis allerede.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Ratebegrens gratistransaksjoner kontinuerlig til <n>*1000 bytes per minutt (standardverdi: %u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>Opprett nye filer med standardtillatelser i systemet, i stedet for umask 077 (kun virksom med lommebokfunksjonalitet slått av)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Oppdag egne IP-adresser (standardverdi: 1 ved lytting og ingen -externalip eller -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Feil: Lytting etter innkommende tilkoblinger feilet (lytting returnerte feil %s)</translation> </message> @@ -3063,10 +3069,6 @@ Adresse: %4 <translation>Gebyrer (i BTC/Kb) mindre enn dette anses som null gebyr for videresending (standardverdi: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Gebyrer (i BTC/Kb) mindre enn dette anses som null gebyr for laging av transaksjoner (standardverdi: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Hvis paytxfee ikke er angitt, inkluderer da nok i gebyr til at transaksjoner gjennomsnittligt bekreftes innen n blokker (standardverdi: %u)</translation> </message> @@ -3079,16 +3081,16 @@ Adresse: %4 <translation>Maksimal størrelse på data i databærende transaksjoner vi videresender og ufører graving på (standardverdi: %u)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>Maksimal sum av gebyrer som kan brukes i en enkelt lommebokstransaksjon, settes den for lavt kan store transaksjoner bli avbrutt (standardverdi: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Beskjæringsmodus er konfigurert under minimum på %d MB. Vennligst bruk et høyere nummer.</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Søk etter nodeadresser via DNS-oppslag, hvis vi har få adresser å koble til (standard: 1 med mindre -connect)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>Krev høy prioritet for å videreformidle transaksjoner som er gratis eller har lavt gebyr (standardverdi: %u)</translation> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Bruk tilfeldig identitet for hver proxytilkobling. Dette muliggjør TOR stream isolasjon (standardverdi: %u)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3099,6 +3101,10 @@ Adresse: %4 <translation>Angi antall tråder for mynt generering hvis aktivert (-1 = alle kjerner, standardverdi: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Transaksjonsbeløpet er for lite til å sendes etter at gebyret er fratrukket</translation> + </message> + <message> <source>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.</source> <translation>Dette produktet inneholder programvare utviklet av OpenSSL Project for bruk i OpenSSL Toolkit <https://www.openssl.org/> og kryptografisk programvare skrevet av Eric Young og UPnP-programvare skrevet av Thomas Bernard.</translation> </message> @@ -3139,14 +3145,34 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Hvitlistede noder kan ikke DoS-blokkeres, og deres transaksjoner videresendes alltid, selv om de allerede er i minnelageret. Nyttig f.eks. for en gateway.</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Du må gjenoppbygge databasen ved hjelp av -reindex for å gå tilbake til ubeskåret modus. Dette vil laste ned hele blokkjeden på nytt.</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(standardverdi: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Godta offentlige REST forespørsler (standardverdi: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Aktiverer beste kjede...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Kan ikke kjøre med en lommebok i beskjæringsmodus.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Kan ikke løse -whitebind-adresse: '%s'</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Velg datamappe ved oppstart (standard: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Koble til via SOCKS5-proxy</translation> </message> @@ -3227,12 +3253,12 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>RPC-støtte for persistente HTTP-forbindelser (standardverdi: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Slumpvis dropp 1 av hver <n> nettverksmeldinger</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Gjenopprett blokkjedeindeks fra gjeldende blk000??.dat filer ved oppstart</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Slumpvis bland 1 av hver <n> nettverksmeldinger</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Motta og vis P2P nettverksvarsler (standardvalg: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3243,10 +3269,22 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Send transaksjoner uten transaksjonsgebyr hvis mulig (standardverdi: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Sett SSL-rotsertifikat for betalingsetterspørring (standard: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Sett språk, for eksempel "nb_NO" (standardverdi: fra operativsystem)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Vis alle feilsøkingsvalg (bruk: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Vis splashskjerm ved oppstart (standardverdi: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Krymp filen debug.log når klienten starter (standardverdi: 1 hvis uten -debug)</translation> </message> @@ -3255,6 +3293,14 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Signering av transaksjon feilet</translation> </message> <message> + <source>Start minimized</source> + <translation>Start minimert</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Transaksjonsbeløpet er for lite til å betale gebyr</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Dette er eksperimentell programvare.</translation> </message> @@ -3275,6 +3321,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transaksjonen er for stor</translation> </message> <message> + <source>UI Options:</source> + <translation>Innstillinger for Brukergrensesnitt:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Kan ikke binde til %s på denne datamaskinen (binding returnerte feilen %s)</translation> </message> @@ -3295,10 +3345,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Advarsel</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Advarsel: Denne versjonen er foreldet, oppgradering kreves!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Advarsel: Argumentet -benchmark er ikke støttet og ble ignorert, bruk -debug=bench.</translation> </message> @@ -3359,18 +3405,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = behold metadata for transaksjon som f. eks. kontoeier og informasjon om betalingsanmodning, 2 = dropp metadata for transaksjon)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Overfør aktiviteten i databasen fra minnelageret til loggen på harddisken for hver <n> megabytes (standardverdi: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Hvor grundig blokkverifiseringen til -checkblocks er (0-4, standardverdi: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Logg transaksjonsprioritet og gebyr per kB under blokkutvinning (standardverdi: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Oppretthold en full transaksjonsindeks, brukt av getrawtransaction RPC-kall (standardverdi: %u)</translation> </message> @@ -3399,18 +3437,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Alltid søk etter nodeadresser via DNS-oppslag (standardverdi: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Slå av sikkerhetsmodus, overstyr en virkelig sikkerhetsmodushendelse (standardverdi: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Feil ved lasting av wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Tving sikkerhetsmodus (standardverdi: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Generer mynter (standardverdi: %u)</translation> </message> @@ -3427,10 +3457,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ugyldig -proxy adresse: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Begrens størrelsen på hurtigbufferen for signaturer til <n> oppføringer (standardverdi: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Lytt etter JSON-RPC tilkoblinger på <port> (standardverdi: %u eller testnett: %u)</translation> </message> @@ -3443,6 +3469,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Hold maks <n> koblinger åpne til andre noder (standardverdi: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Få lommeboken til å kringkaste transaksjoner</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Maks mottaksbuffer per forbindelse, <n>*1000 bytes (standardverdi: %u)</translation> </message> @@ -3451,10 +3481,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Maks sendebuffer per forbindelse, <n>*1000 bytes (standardverdi: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Aksepter kun blokkjeden som stemmer med innebygde sjekkpunkter (standardvalg: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Sett inn tidsstempel i front av feilsøkingsdata (standardverdi: %u)</translation> </message> @@ -3467,10 +3493,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Videresend ikke-P2SH multisig (standardverdi: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Kjør en tråd som skriver lommeboken til disk periodisk (standardverdi: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Fil for tjenersertifikat (standardverdi: %s)</translation> </message> @@ -3491,10 +3513,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Sett antall tråder til betjening av RPC-kall (standardverdi: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Setter flagget DB_PRIVATE i miljøet til lommebokdatabasen (standardverdi: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Angi konfigurasjonsfil (standardverdi: %s)</translation> </message> @@ -3511,10 +3529,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Bruk ubekreftet veksel ved sending av transaksjoner (standardverdi: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Avslutt etter import av blokker fra disk (standardverdi: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Grenseverdi for å koble fra noder med dårlig oppførsel (standardverdi: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index 998f8f3590..7999e263e4 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -1,4 +1,4 @@ -<TS language="nl" version="2.1"> +<TS language="nl" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ <translation>Wijzig wachtwoord</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Vul uw oude en nieuwe portemonneewachtwoord in.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Bevestig versleuteling van de portemonnee</translation> </message> @@ -172,6 +168,10 @@ <translation>Weet u zeker dat u uw portemonnee wilt versleutelen?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -185,11 +185,11 @@ </message> <message> <source>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>.</source> - <translation>Voer een nieuw wachtwoord in voor uw portomonee.<br/>Gebruik een wachtwoord van <b>tien of meer willekeurige karakters</b>, of <b>acht of meer woorden</b>.</translation> + <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin zal nu afsluiten om het versleutelingsproces te voltooien. Onthoudt dat het versleutelen van uw portemonnee u niet volledig kan beschermen: Malware kan uw computer infecteren en uw bitcoins stelen.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Voer het oude en nieuwe wachtwoord in voor uw portemonnee.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>Verstuur munten naar een Bitcoinadres</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Wijzig instellingen van Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Backup portemonnee naar een andere locatie</translation> </message> @@ -403,6 +399,10 @@ <translation>&Over Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Wijzig configuratieopties voor Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Toon de lijst met gebruikt verzend adressen en labels</translation> </message> @@ -431,6 +431,10 @@ <translation>Geen bron voor blokken beschikbaar...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>%n blok aan transactie geschiedenis verwerkt.</numerusform><numerusform>%n blokken aan transactie geschiedenis verwerkt.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n uur</numerusform><numerusform>%n uur</numerusform></translation> </message> @@ -478,35 +482,49 @@ <source>Up to date</source> <translation>Bijgewerkt</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>%n Blok transactie geschiedenis verwerkt.</numerusform><numerusform>%n Blokken transactie geschiedenis verwerkt.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Aan het bijwerken...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Verzonden transactie</translation> + <source>Date: %1 +</source> + <translation>Datum: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Binnenkomende transactie</translation> + <source>Amount: %1 +</source> + <translation>Aantal: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Datum: %1 -Bedrag: %2 -Type: %3 -Adres: %4 + <translation>Type: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Label: %1 </translation> </message> <message> + <source>Address: %1 +</source> + <translation>Adres: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Verzonden transactie</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Binnenkomende transactie</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Portemonnee is <b>versleuteld</b> en momenteel <b>geopend</b></translation> </message> @@ -697,6 +715,18 @@ Adres: %4 <translation>geen</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Dit label wordt rood als de transactie groter is dan 1000 bytes.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Dit label wordt rood als de prioriteit lager is dan "gemiddeld".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Dit label wordt rood wanneer een ontvanger minder dan %1 krijgt.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Kan per input +/- %1 satoshi(s) variëren.</translation> </message> @@ -709,10 +739,6 @@ Adres: %4 <translation>nee</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Dit label wordt rood, als de transactie grootte meer dan 1000 bytes is.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Dit betekent dat een vergoeding van minimaal %1 per kB nodig is.</translation> </message> @@ -725,14 +751,6 @@ Adres: %4 <translation>Transacties met een hogere prioriteit zullen eerder in een block gezet worden.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Als dit label rood is, is de prioriteit minder dan "medium".</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Dit label wordt rood, als een ontvanger een bedrag van minder dan %1 gekregen heeft.</translation> - </message> - <message> <source>(no label)</source> <translation>(geen label)</translation> </message> @@ -853,30 +871,6 @@ Adres: %4 <source>command-line options</source> <translation>commandoregel-opties</translation> </message> - <message> - <source>UI options</source> - <translation>gebruikersinterfaceopties</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Stel taal in, bijvoorbeeld ''de_DE" (standaard: systeeminstellingen)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Geminimaliseerd starten</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Zet SSL root certificaten voor betalingsverzoek (standaard: -sytem-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Laat laadscherm zien bij het opstarten. (standaard: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Kies de gegevensmap tijdens het opstarten (standaard: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -959,14 +953,6 @@ Adres: %4 <translation>&Algemeen</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Start Bitcoin automatisch na inloggen in het systeem</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>Start &Bitcoin bij het inloggen in het systeem</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Grootte van de &database cache</translation> </message> @@ -991,6 +977,14 @@ Adres: %4 <translation>IP-adres van de proxy (bijv. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Stel hier de taal van de applicatie in. Deze instelling zal van kracht worden na het herstarten van de applicatie.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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 |. </translation> </message> @@ -1015,6 +1009,14 @@ Adres: %4 <translation>&Netwerk</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Bitcoin Kern automatisch starten bij inloggen.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Start Bitcoin Kern tijdens login.</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = laat dit aantal kernen vrij)</translation> </message> @@ -1079,10 +1081,6 @@ Adres: %4 <translation>&Minimaliseer naar het systeemvak in plaats van de taakbalk</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimaliseer het venster in de plaats van de applicatie af te sluiten als het venster gesloten wordt. Wanneer deze optie aan staan, kan de applicatie alleen worden afgesloten door Afsluiten te kiezen in het menu.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>Minimaliseer bij sluiten van het &venster</translation> </message> @@ -1095,10 +1093,6 @@ Adres: %4 <translation>Taal &Gebruikersinterface:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>De taal van de gebruikersinterface kan hier ingesteld worden. Deze instelling zal pas van kracht worden nadat Bitcoin herstart wordt.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Eenheid om bedrag in te tonen:</translation> </message> @@ -1135,8 +1129,8 @@ Adres: %4 <translation>Herstart van de client is vereist om veranderingen door te voeren.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>De client zal worden afgesloten, wilt u doorgaan?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Applicatie zal worden afgesloten. Wilt u doorgaan?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1221,10 +1215,6 @@ Adres: %4 <source>Current total balance in watch-only addresses</source> <translation>Huidige balans in alleen-bekijkbare adressen.</translation> </message> - <message> - <source>out of sync</source> - <translation>niet gesynchroniseerd</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1245,10 +1235,6 @@ Adres: %4 <translation>Betalingsaanvraagnetwerk komt niet overeen met klantennetwerk.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Betalingsverzoek is verlopen.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Betalingsaanvraag is niet geïnitialiseerd.</translation> </message> @@ -1281,10 +1267,18 @@ Adres: %4 <translation>Betalingsverzoek-bestand kan niet gelezen of verwerkt worden! Dit kan veroorzaakt worden door een ongeldig betalingsverzoek-bestand.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Betalingsverzoek verlopen.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Niet-geverifieerde betalingsverzoeken naar aangepaste betaling scripts worden niet ondersteund.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Ongeldig betalingsverzoek.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Restitutie van %1</translation> </message> @@ -1324,10 +1318,6 @@ Adres: %4 <translation>User Agent</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Adres/Hostnaam</translation> - </message> - <message> <source>Ping Time</source> <translation>Ping tijd</translation> </message> @@ -1359,14 +1349,6 @@ Adres: %4 <translation>%1s</translation> </message> <message> - <source>NETWORK</source> - <translation>Netwerk</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>ONBEKEND</translation> - </message> - <message> <source>None</source> <translation>Geen</translation> </message> @@ -1457,6 +1439,10 @@ Adres: %4 <translation>Huidig aantal blokken</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Open het Bitcoin Core debug logbestand van de huidige gegevens directory. Dit kan enkele seconden duren voor grote logbestanden.</translation> + </message> + <message> <source>Received</source> <translation>Ontvangen</translation> </message> @@ -1565,16 +1551,12 @@ Adres: %4 <translation>Debug-logbestand</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Open het Bitcoindebug-logbestand van de huidige datamap. Dit kan een aantal seconden duren voor grote logbestanden.</translation> - </message> - <message> <source>Clear console</source> <translation>Maak console leeg</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Welkom bij de Bitcoin RPC-console.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Welkom op de Bitcoin Core RPC console.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1865,14 +1847,6 @@ Adres: %4 <translation>Transactiekosteninstellingen verbergen</translation> </message> <message> - <source>Minimize</source> - <translation>Minimaliseer</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Als de aangepaste toeslag is ingesteld op 1000 satoshis en de transactie is maar 250 bytes, dan wordt bij "per kilobyte" 250 satoshis aan toeslag berekend, terwijl er bij "tenminste" 1000 satoshis worden berekend. Voor transacties die groter zijn dan een kilobyte, wordt in beide gevallen per kilobyte de toeslag berekend.</translation> - </message> - <message> <source>per kilobyte</source> <translation>per kilobyte</translation> </message> @@ -1881,6 +1855,10 @@ Adres: %4 <translation>Als de aangepaste toeslag is ingesteld op 1000 satoshis en de transactie is maar 250 bytes, dan wordt bij "per kilobyte" 250 satoshis aan toeslag berekend, terwijl er bij "totaal tenminste" 1000 satoshis worden berekend. Voor transacties die groter zijn dan een kilobyte, wordt in beide gevallen per kilobyte de toeslag berekend.</translation> </message> <message> + <source>Hide</source> + <translation>Verbergen</translation> + </message> + <message> <source>total at least</source> <translation>totaal ten minste</translation> </message> @@ -2001,10 +1979,6 @@ Adres: %4 <translation>of</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Het ontvangstadres is niet geldig, controleer uw invoer.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Het ingevoerde bedrag moet groter zijn dan 0.</translation> </message> @@ -2017,10 +1991,6 @@ Adres: %4 <translation>Totaal overschrijdt uw huidige saldo wanneer de %1 transactiekosten worden meegerekend</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Dubbel adres gevonden, u kunt slechts eenmaal naar een bepaald adres verzenden per verstuurtransactie</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Transactie creatie niet gelukt!</translation> </message> @@ -2029,16 +1999,20 @@ Adres: %4 <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> - <translation>Transactiekosten hoger dan %1 worden gezien als waanzinnig hoog.</translation> + <source>Payment request expired.</source> + <translation>Betalingsverzoek verlopen.</translation> </message> <message> <source>Pay only the minimum fee of %1</source> <translation>Betaal alleen de minimale transactiekosten van %1</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Beginnen van bevesting geschat binnen %1 blok(ken).</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Het adres van de ontvanger is niet geldig. Gelieve opnieuw te controleren..</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Dubbel adres gevonden: adressen mogen maar één keer worden gebruikt worden.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2116,7 +2090,11 @@ Adres: %4 <translation>Bericht:</translation> </message> <message> - <source>This is a verified payment request.</source> + <source>This is an unauthenticated payment request.</source> + <translation>Dit is een niet-geverifieerd betalingsverzoek.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> <translation>Dit is een geverifieerd betalingsverzoek.</translation> </message> <message> @@ -2128,10 +2106,6 @@ Adres: %4 <translation>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.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Dit is een ongeverifieerd betalingsverzoek.</translation> - </message> - <message> <source>Pay To:</source> <translation>Betaal Aan:</translation> </message> @@ -2162,8 +2136,8 @@ Adres: %4 <translation>O&nderteken Bericht</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>U kunt berichten ondertekenen met een van uw adressen om te bewijzen dat u dit adres bezit. Pas op dat u geen onduidelijke dingen ondertekent, want phishingaanvallen zouden u kunnen misleiden om zo uw identiteit te stelen. Onderteken alleen berichten waarmee u het volledig eens bent.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>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.</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2218,10 +2192,6 @@ Adres: %4 <translation>&Verifiëer Bericht</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Voer het ondertekenende adres, bericht en handtekening hieronder in (let erop dat u nieuwe regels, spaties en tabs juist overneemt) om de handtekening te verifiëren. Let erop dat u niet meer uit het bericht interpreteert dan er daadwerkelijk staat, om te voorkomen dat u wordt misleid in een man-in-the-middle-aanval.</translation> - </message> - <message> <source>The Bitcoin address the message was signed with</source> <translation>Het Bitcoin adres waarmee het bericht ondertekend is</translation> </message> @@ -2485,10 +2455,6 @@ Adres: %4 <translation>Type</translation> </message> <message> - <source>Address</source> - <translation>Adres</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>immatuur (%1 bevestigingen, zal beschikbaar zijn na %2)</translation> </message> @@ -2517,6 +2483,10 @@ Adres: %4 <translation>Niet verbonden</translation> </message> <message> + <source>Label</source> + <translation>Label</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Onbevestigd</translation> </message> @@ -2573,10 +2543,6 @@ Adres: %4 <translation>Of er een alleen-bekijken adres is betrokken bij deze transactie.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Ontvangend adres van transactie.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Bedrag verwijderd van of toegevoegd aan saldo</translation> </message> @@ -2827,18 +2793,10 @@ Adres: %4 <translation>Uitgegeven onder de MIT software licentie, zie het bijgevoegde bestand COPYING of <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Schakel regressietest-modus in, die een speciale blokketen gebruikt waarin blokken onmiddellijk opgelost kunnen worden.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Voer opdracht uit zodra een portemonneetransactie verandert (%s in cmd wordt vervangen door TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>In deze modus, -genproclimit controleert hoeveel blokken er onmiddellijk worden gegenereerd.</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>Kies het aantal script verificatie processen (%u tot %d, 0 = auto, <0 = laat dit aantal kernen vrij, standaard: %d)</translation> </message> @@ -2851,6 +2809,10 @@ Adres: %4 <translation>Niet in staat om %s te verbinden op deze computer. Bitcoin Core draait waarschijnlijk al.</translation> </message> <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>WAARSCHUWING: controleer uw netwerkverbinding, %d blokken ontvangen in de laatste %d uren (%d verwacht)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Waarschuwing: -paytxfee is zeer hoog ingesteld. Dit zijn de transactiekosten die u betaalt bij het versturen van een transactie.</translation> </message> @@ -2907,10 +2869,6 @@ Adres: %4 <translation>Foutopsporing/Testopties:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Ontdek eigen IP-adres (standaard: 1 als er wordt geluisterd en geen -externalip is opgegeven)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Laad de wallet niet en schakel wallet RPC oproepen uit</translation> </message> @@ -2971,10 +2929,6 @@ Adres: %4 <translation>Verbind alleen met nodes in netwerk <net> (ipv4, ipv6 of onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Blokketen opnieuw opbouwen met behulp van huidige blk000??.dat-bestanden</translation> - </message> - <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Zet database cache grootte in megabytes (%d tot %d, standaard: %d)</translation> </message> @@ -2987,10 +2941,6 @@ Adres: %4 <translation>Specificeer het portemonnee bestand (vanuit de gegevensmap)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Dit is bedoeld voor regressie test toepassingen en applicatie onwikkeling.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Gebruik UPnP om de luisterende poort te mappen (standaard: %u)</translation> </message> @@ -3011,6 +2961,10 @@ Adres: %4 <translation>Portemonnee instellingen:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Waarschuwing: Deze versie is verouderd; upgraden verplicht!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Om -txindex te kunnen veranderen dient u de database opnieuw te bouwen met gebruik van -reindex.</translation> </message> @@ -3039,10 +2993,6 @@ Adres: %4 <translation>Kan geen lock verkrijgen op gegevensmap %s. Bitcoin Core draait waarschijnlijk al.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Doorlopend tarief-limiet op gratis transacties toepassen tot <n>*1000 bytes per minuut (standaard: %u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>Creër nieuwe bestanden met standaard systeem bestandsrechten in plaats van umask 077 (alleen effectief met uitgeschakelde portemonnee functionaliteit)</translation> </message> @@ -3063,10 +3013,6 @@ Adres: %4 <translation>Toeslagen (in BTC/Kb) kleiner dan dit worden beschouwd als geen vergoeding (voor doorgeven) (standaard: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Toeslagen (in BTC/Kb) kleiner dan dit worden beschouwd als geen vergoeding transactieaanmaak (standaard: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Als paytxfee niet is ingesteld, het pakket voldoende vergoeding zodat transacties beginnen bevestiging gemiddeld binnen in blokken (default: %u)</translation> </message> @@ -3080,18 +3026,10 @@ Adres: %4 (default: %u)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>Maximale totale kosten om te gebruiken in een enkele portemonnee transactie , vaststellen van een te laag kan grote transacties af te breken (default: %s)</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Query voor peer- adressen via DNS- lookup , als laag op adressen (default: 1 unless -connect)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>Vereisen een hoge prioriteit voor het doorgeven van gratis of tegen lage vergoeding transacties (default:%u)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Stel maximumgrootte in bytes in voor hoge-prioriteits-/lage-transactiekosten-transacties (standaard: %d)</translation> </message> @@ -3100,10 +3038,37 @@ Adres: %4 <translation>Stel het aantal threads in voor het genereren van coins indien ingesteld (-1 = alle kernen, standaard: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Het transactiebedrag is te klein om te versturen nadat de vergoeding in mindering is gebracht</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> <message> + <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: +%s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +The username and password MUST NOT be the same. +If the file does not exist, create it with owner-readable-only file permissions. +It is also recommended to set alertnotify so you are notified of problems; +for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com +</source> + <translation>Om bitcoind of de -server optie naar bitcoin-gt te gebruiken, dient u een rpcwachtwoord in te stellen in het configuratiebestand: + %s +Wij raden u aan om het volgende wachtwoord willekeurig te gebruiken: +rpcuser=bitcoinrpc +rpcpassword=%s +(u hoeft dit wachtwoord niet te onthouden) +De gebruikersnaam en het wachtwoorden moeten NIET hetzelfde zijn. +Indien het bestand niet bestaat, maak het bestand aan met bestandsrechten: alleen lezen voor eigenaar. +Het is ook aan te raden om een alarmnotificatie in te stellen, zodat u op de hoogte bent van de problemen; +Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> + </message> + <message> <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> <translation>Let op: -maxtxfee is erg hoog ingesteld! Transactiekosten van dergelijke groottes kunnen in een enkele transactie worden betaald.</translation> </message> @@ -3116,14 +3081,26 @@ Adres: %4 <translation>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</translation> </message> <message> + <source>(default: %u)</source> + <translation>(standaard: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Accepteer publieke REST-requests (standaard: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Beste reeks activeren...</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Kan -whitebind adres niet herleiden: '%s'</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Kies de gegevensmap tijdens het opstarten (standaard: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Verbind door SOCKS5 proxy</translation> </message> @@ -3204,14 +3181,6 @@ Adres: %4 <translation>RPC ondersteuning voor HTTP persisten verbindingen (default: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Laat willekeurig 1 elke <n> netwerkberichten vallen</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Fuzz willekeurig 1 van elke <n> netwerkberichten</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Stuur trace/debug-info naar de console in plaats van het debug.log bestand</translation> </message> @@ -3220,10 +3189,22 @@ Adres: %4 <translation>Verstuur transacties zonder verzendkosten indien mogelijk (standaard: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Zet SSL root certificaten voor betalingsverzoek (standaard: -sytem-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Stel taal in, bijvoorbeeld ''de_DE" (standaard: systeeminstellingen)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Toon alle foutopsporingsopties (gebruik: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Laat laadscherm zien bij het opstarten. (standaard: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Verklein debug.log-bestand bij het opstarten van de client (standaard: 1 als geen -debug)</translation> </message> @@ -3232,6 +3213,14 @@ Adres: %4 <translation>Ondertekenen van transactie mislukt</translation> </message> <message> + <source>Start minimized</source> + <translation>Geminimaliseerd starten</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Het transactiebedrag is te klein om de vergoeding te betalen</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Dit is experimentele software.</translation> </message> @@ -3252,6 +3241,10 @@ Adres: %4 <translation>Transactie te groot</translation> </message> <message> + <source>UI Options:</source> + <translation>UI Opties:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Niet in staat om aan %s te binden op deze computer (bind gaf error %s)</translation> </message> @@ -3272,10 +3265,6 @@ Adres: %4 <translation>Waarschuwing</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Waarschuwing: Deze versie is verouderd, een upgrade is vereist!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Waarschuwing: Niet ondersteund argument -benchmark genegeerd, gebruik -debug=bench.</translation> </message> @@ -3336,18 +3325,10 @@ Adres: %4 <translation>(1 = behoudt tx meta data bijv. account eigenaar en betalingsverzoek informatie, 2. sla tx meta data niet op)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Leeg database-activiteit uit de geheugen pool naar schijf log elke <n> megabytes (standaard: %u) </translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Hoe grondig de blokverificatie van -checkblocks is (0-4, standaard: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Log transactieprioriteit en -kosten per kB bij het mijnen van blokken (standaard: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Onderhoud een volledige transactieindex, gebruikt door de getrawtransaction rpc call (standaard: %u)</translation> </message> @@ -3372,18 +3353,10 @@ Adres: %4 <translation>Vind anderen door middel van een DNS-naslag (standaard: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Veilige modus uitschakelen, hef een echte veilige modus gebeurtenis uit (default: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Fout bij laden wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Forceer veilige modus (default: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Genereer munten (standaard: %u)</translation> </message> @@ -3400,10 +3373,6 @@ Adres: %4 <translation>Ongeldig -proxy adres: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Limiteer grootte van de handtekening cache tot <n> entries (default: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Luister naar JSON-RPC-verbindingen op poort <port> (standaard: %u of testnet: %u)</translation> </message> @@ -3416,6 +3385,10 @@ Adres: %4 <translation>Onderhoud maximaal <n> verbindingen naar peers (standaard: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Laat de portemonnee transacties uitsturen</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Maximum per-connectie ontvangstbuffer, <n>*1000 bytes (standaard: %u)</translation> </message> @@ -3424,10 +3397,6 @@ Adres: %4 <translation>Maximum per-connectie zendbuffer, <n>*1000 bytes (standaard: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Accepteer alleen blokkenketen die overeenkomt met de ingebouwde checkpoints (standaard: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Prepend debug output met tijdstempel (standaard: %u)</translation> </message> @@ -3440,10 +3409,6 @@ Adres: %4 <translation>Relay non-P2SH multisig (default: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Draai een proces om de wallet periodiek te flushen (default: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Certificaat-bestand voor server (standaard: %s)</translation> </message> @@ -3464,10 +3429,6 @@ Adres: %4 <translation>Stel het aantal threads in om RPC-aanvragen mee te bedienen (standaard: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Plaatst de DB_PRIVATE vlag in de wallet db omgeving (default: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Specificeer configuratie bestand (standaard: %s)</translation> </message> @@ -3484,10 +3445,6 @@ Adres: %4 <translation>Besteed onbevestigd wisselgeld bij het versturen van transacties (standaard: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Stop uitvoeren na het importeren van blokken van de schijf (standaard: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Drempel om verbinding te verbreken naar zich misdragende peers (standaard: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_pam.ts b/src/qt/locale/bitcoin_pam.ts index 355d167271..4939dff4b0 100644 --- a/src/qt/locale/bitcoin_pam.ts +++ b/src/qt/locale/bitcoin_pam.ts @@ -1,7 +1,11 @@ -<TS language="pam" version="2.1"> +<TS language="pam" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>I-right click ban alilan ing address o libel</translation> + </message> + <message> <source>Create a new address</source> <translation>Maglalang kang bayung address</translation> </message> @@ -47,7 +51,7 @@ </message> <message> <source>Sending addresses</source> - <translation>Address king pamag-Padala</translation> + <translation>Address king pamag-Send</translation> </message> <message> <source>Receiving addresses</source> @@ -132,10 +136,6 @@ <translation>Alilan ya ing passphrase</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Palub ye ing luma ampo ing bayung passphrase king wallet.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Kumpirman ya ing wallet encryption</translation> </message> @@ -160,10 +160,6 @@ <translation>Me-encrypt ne ing wallet</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Ing Bitcoin ngeni magsara ya ban ayari ing proseso ning pamag-encrypt. Tandanan yu king pamag-encrypt wallet, ali nala aprotektan king kabuuan reng bitcoins yu kareng malware a kasalunsungan atiu kareng computer yu.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>Memali ya ing pamag-encrypt king wallet </translation> </message> @@ -255,10 +251,6 @@ <translation>Magpadalang barya king Bitcoin address</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Alilan ing pipamilian konpigurasion para keng Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>I-backup ing wallet king aliwang lugal</translation> </message> @@ -351,18 +343,6 @@ <translation>Paparatang a transaksion</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Aldo: %1 -Alaga: %2 -Type: %3 -Address: %4 -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Maka-<b>encrypt</b> ya ing wallet at kasalukuyan yang maka-<b>unlocked</b></translation> </message> @@ -481,23 +461,7 @@ Address: %4 <source>command-line options</source> <translation>pipamilian command-line</translation> </message> - <message> - <source>UI options</source> - <translation>Pipamilian ning UI</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Mamiling Amanu, alimbawa "de_DE"(default: system locale)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Umpisan ing pamaglati</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Ipalto ing splash screen keng umpisa (default: 1)</translation> - </message> - </context> +</context> <context> <name>Intro</name> <message> @@ -527,14 +491,6 @@ Address: %4 <translation>&Pun</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Umpisan yang antimu ing Bitcoin kaibat mekapag-log in king sistema.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Umpisan ya ing Bitcoin king pamag-log-in na ning sistema.</translation> - </message> - <message> <source>&Network</source> <translation>&Network</translation> </message> @@ -571,10 +527,6 @@ Address: %4 <translation>&Latian ya ing tray kesa king taskbar</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Palatian namu kesa king iluwal ya ing aplikasion istung makasara ya ing awang. Istung ing pipamilian a ini atiu king "magsilbi", ing aplikasion misara yamu kaibat meng pinili ing "Tuknangan" king menu.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>P&alatian istung isara</translation> </message> @@ -587,10 +539,6 @@ Address: %4 <translation>Amanu na ning user interface:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Ing amanu na ning user interface maliari yang i-ayus o ilage keni. Ing ayus a ini magsilbi yamu istung pesibayuan meng pasibayu ing Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>Ing &Unit a ipakit king alaga ning:</translation> </message> @@ -649,11 +597,7 @@ Address: %4 <source>Your current total balance</source> <translation>Ing kekang kasalungsungan kabuuang balanse</translation> </message> - <message> - <source>out of sync</source> - <translation>ali ya maka-sync</translation> - </message> -</context> + </context> <context> <name>PaymentServer</name> </context> @@ -741,18 +685,10 @@ Address: %4 <translation>Debug log file</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Ibuklat ing Bitcoin debug log file menibat king kasalungsungan data directory. Magluat ya ining pilan segundu para kareng mamaragul a log files.</translation> - </message> - <message> <source>Clear console</source> <translation>I-Clear ing console</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Malaus kayu king Bitcoin RPC console.</translation> - </message> - <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Gamitan me ing patas at pababang arrow para alibut me ing kasalesayan, at <b>Ctrl-L</b> ban I-clear ya ing screen.</translation> </message> @@ -857,10 +793,6 @@ Address: %4 <translation>Kopyan ing alaga</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Ing address na ning tumanggap ali ya katanggap-tanggap, maliari pung pakilaue pasibayu.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Ing alaga na ning bayaran dapat mung mas matas ya king 0.</translation> </message> @@ -873,10 +805,6 @@ Address: %4 <translation>Ing kabuuan mipasobra ya king kekang balanse istung inabe ya ing %1 a bayad king transaksion </translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Atin meakit a milupang address, maliari kamung magpadalang misan king metung a address king misan a pamagpadalang transaksion.</translation> - </message> - <message> <source>(no label)</source> <translation>(alang label)</translation> </message> @@ -926,10 +854,6 @@ Address: %4 <translation>&Pirman ing Mensayi</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Maliari kang mamirmang mensayi king kekang address bilang patune na keka ya ini. Mimingat mu king pamag-pirmang e malino uling mapalyari kang mabiktimang phishing attack a manloku keka na pirman me ing sarili mu para king karela. Only sign fully-detailed statements you agree to.</translation> - </message> - <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1185,10 +1109,6 @@ Address: %4 <translation>Klase</translation> </message> <message> - <source>Address</source> - <translation>Address</translation> - </message> - <message> <source>Open until %1</source> <translation>Makabuklat anggang %1</translation> </message> @@ -1205,6 +1125,10 @@ Address: %4 <translation>Me-generate ya oneng ali ya metanggap</translation> </message> <message> + <source>Label</source> + <translation>Label</translation> + </message> + <message> <source>Received with</source> <translation>Atanggap kayabe ning</translation> </message> @@ -1241,10 +1165,6 @@ Address: %4 <translation>Klase ning transaksion</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Kepuntalan a address ning transaksion</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Alagang milako o miragdag king balanse.</translation> </message> @@ -1431,10 +1351,6 @@ Address: %4 <translation>Mekapansin lang me-corrupt a block database</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>I-discover ing sariling IP address (default: 1 istung makiramdam at -externalip)</translation> - </message> - <message> <source>Do you want to rebuild the block database now?</source> <translation>Buri meng buuan pasibayu ing block database ngene?</translation> </message> @@ -1463,6 +1379,18 @@ Address: %4 <translation>Magpadalang trace/debug info okeng console kesa keng debug.log file</translation> </message> <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Mamiling Amanu, alimbawa "de_DE"(default: system locale)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Ipalto ing splash screen keng umpisa (default: 1)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Umpisan ing pamaglati</translation> + </message> + <message> <source>Transaction too large</source> <translation>Maragul yang masiadu ing transaksion</translation> </message> @@ -1475,10 +1403,6 @@ Address: %4 <translation>Kapabaluan</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Kapabaluan: Ing bersioin a ini laus ne, kailangan nang mag-upgrade!</translation> - </message> - <message> <source>Password for JSON-RPC connections</source> <translation>Password para king JSON-RPC koneksion</translation> </message> diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index d139f9560e..5bc7df0aca 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -1,9 +1,9 @@ -<TS language="pl" version="2.1"> +<TS language="pl" version="2.0"> <context> <name>AddressBookPage</name> <message> <source>Right-click to edit address or label</source> - <translation>Prawy klik żeby edytować adres lub etykietę</translation> + <translation>Kliknij prawy przycisk aby edytować adres lub etykietę</translation> </message> <message> <source>Create a new address</source> @@ -87,7 +87,7 @@ </message> <message> <source>Comma separated file (*.csv)</source> - <translation>Plik *.CSV (rozdzielany przecinkami)</translation> + <translation>CSV (rozdzielany przecinkami)</translation> </message> <message> <source>Exporting Failed</source> @@ -156,10 +156,6 @@ <translation>Zmień hasło</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Podaj stare i nowe hasło do portfela.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Potwierdź szyfrowanie portfela</translation> </message> @@ -172,6 +168,10 @@ <translation>Jesteś pewien, że chcesz zaszyfrować swój portfel?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -188,8 +188,8 @@ <translation>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></translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Program Bitcoin 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.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Podaj stare i nowe hasło do portfela.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>Wyślij monety na adres Bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Zmienia opcje konfiguracji bitcoina</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Zapasowy portfel w innej lokalizacji</translation> </message> @@ -403,6 +399,10 @@ <translation>&O Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Zmień opcje konfiguracji dla Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Pokaż listę adresów i etykiet użytych do wysyłania</translation> </message> @@ -424,23 +424,23 @@ </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n aktywne połączenie do sieci Bitcoin</numerusform><numerusform>%n aktywne połączenia do sieci Bitcoin</numerusform><numerusform>%n aktywnych połączeń do sieci Bitcoin</numerusform></translation> + <translation><numerusform>%n aktywnych połączeń do sieci Bitcoin</numerusform><numerusform>%n aktywnych połączeń do sieci Bitcoin</numerusform><numerusform>%n aktywnych połączeń do sieci Bitcoin</numerusform></translation> </message> <message> <source>No block source available...</source> <translation>Brak dostępnych źródeł bloków...</translation> </message> <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n godzina</numerusform><numerusform>%n godzin</numerusform><numerusform>%n godzin</numerusform></translation> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Przetworzono %n bloków historii transakcji.</numerusform><numerusform>Przetworzono %n bloków historii transakcji.</numerusform><numerusform>Przetworzono %n bloków historii transakcji.</numerusform></translation> </message> <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n dzień</numerusform><numerusform>%n dni</numerusform><numerusform>%n dni</numerusform></translation> + <source>%n hour(s)</source> + <translation><numerusform>%n godzin</numerusform><numerusform>%n godzin</numerusform><numerusform>%n godzin</numerusform></translation> </message> <message numerus="yes"> <source>%n week(s)</source> - <translation><numerusform>%n tydzień</numerusform><numerusform>%n tygodni</numerusform><numerusform>%n tygodni</numerusform></translation> + <translation><numerusform>%n tygodni</numerusform><numerusform>%n tygodni</numerusform><numerusform>%n tygodni</numerusform></translation> </message> <message> <source>%1 and %2</source> @@ -448,7 +448,7 @@ </message> <message numerus="yes"> <source>%n year(s)</source> - <translation><numerusform>%n rok</numerusform><numerusform>%n lata</numerusform><numerusform>%n lat</numerusform></translation> + <translation><numerusform>%n lat</numerusform><numerusform>%n lat</numerusform><numerusform>%n lat</numerusform></translation> </message> <message> <source>%1 behind</source> @@ -478,35 +478,49 @@ <source>Up to date</source> <translation>Aktualny</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>Przetworzono %n blok historii transakcji.</numerusform><numerusform>Przetworzono %n bloki historii transakcji.</numerusform><numerusform>Przetworzono %n bloków historii transakcji.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Synchronizuję się...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Transakcja wysłana</translation> + <source>Date: %1 +</source> + <translation>Data: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Transakcja przychodząca</translation> + <source>Amount: %1 +</source> + <translation>Kwota: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Data: %1 -Kwota: %2 -Typ: %3 -Adres: %4 + <translation>Typ: %1 </translation> </message> <message> + <source>Label: %1 +</source> + <translation>Etykieta: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Adres: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Transakcja wysłana</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Transakcja przychodząca</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Portfel jest <b>zaszyfrowany</b> i obecnie <b>odblokowany</b></translation> </message> @@ -646,7 +660,7 @@ Adres: %4 </message> <message> <source>Copy dust</source> - <translation>Kopiuj pył</translation> + <translation>Kopiuj kurz</translation> </message> <message> <source>Copy change</source> @@ -697,6 +711,18 @@ Adres: %4 <translation>żaden</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Ta etykieta staje się czerwona, kiedy transakcja jest większa niż 1000 bajtów.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Ta etykieta jest czerwona, jeżeli priorytet jest mniejszy niż "średni"</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Etykieta staje się czerwona kiedy którykolwiek odbiorca otrzymuje kwotę mniejszą niż %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Waha się +/- %1 satoshi na wejście.</translation> </message> @@ -709,10 +735,6 @@ Adres: %4 <translation>nie</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Ta etykieta staje się czerwona, kiedy transakcja jest większa niż 1000 bajtów.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Oznacza to wymaganą opłatę minimum %1 na kB.</translation> </message> @@ -725,14 +747,6 @@ Adres: %4 <translation>Transakcje o wyższym priorytecie zwykle szybciej zostają dołączone do bloku.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Ta etykieta jest czerwona, jeżeli priorytet jest mniejszy niż "średni"</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Etykieta staje się czerwona kiedy którykolwiek odbiorca otrzymuje kwotę mniejszą niż %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(brak etykiety)</translation> </message> @@ -853,30 +867,6 @@ Adres: %4 <source>command-line options</source> <translation>opcje konsoli</translation> </message> - <message> - <source>UI options</source> - <translation>Opcje UI</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Ustaw Język, na przykład "pl_PL" (domyślnie: systemowy)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Uruchom zminimalizowany</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Ustaw certyfikaty główne SSL dla żądań płatności (domyślnie: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Pokazuj okno powitalne przy starcie (domyślnie: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Wybierz folder danych przy starcie (domyślnie: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -922,7 +912,7 @@ Adres: %4 </message> <message numerus="yes"> <source>(of %n GB needed)</source> - <translation><numerusform>(z %n GB potrzebnego)</numerusform><numerusform>(z %n GB potrzebnych)</numerusform><numerusform>(z %n GB potrzebnych)</numerusform></translation> + <translation><numerusform>(z %n GB potrzebnych)</numerusform><numerusform>(z %n GB potrzebnych)</numerusform><numerusform>(z %n GB potrzebnych)</numerusform></translation> </message> </context> <context> @@ -959,14 +949,6 @@ Adres: %4 <translation>Główne</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Automatycznie uruchamia Bitcoin po zalogowaniu do systemu.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>Uruchamiaj Bitcoin wraz z zalogowaniem do &systemu</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Wielkość bufora bazy &danych</translation> </message> @@ -991,6 +973,22 @@ Adres: %4 <translation>Adres IP serwera proxy (np. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Można tu ustawić język interfejsu uzytkownika. Żeby ustawienie przyniosło skutek trzeba uruchomić ponownie Bitcoin.</translation> + </message> + <message> + <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> + <translation>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ą |.</translation> + </message> + <message> + <source>Third party transaction URLs</source> + <translation>Zewnętrzny URL podglądu transakcji</translation> + </message> + <message> <source>Active command-line options that override above options:</source> <translation>Aktywne opcje linii komend, które nadpisują powyższe opcje:</translation> </message> @@ -1007,6 +1005,14 @@ Adres: %4 <translation>&Sieć</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Automatycznie uruchamia Bitcoin po zalogowaniu do systemu.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>Uruchamiaj Bitcoin wraz z zalogowaniem do &systemu</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = automatycznie, <0 = zostaw tyle wolnych rdzeni)</translation> </message> @@ -1023,6 +1029,10 @@ Adres: %4 <translation>Włącz funk&cje kontoli monet</translation> </message> <message> + <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source> + <translation>Jeżeli wyłączysz możliwość wydania niezatwierdzonej wydanej reszty, reszta z transakcji nie będzie mogła zostać wykorzystana, dopóki ta transakcja nie będzie miała przynajmniej jednego potwierdzenia. To także ma wpływ na obliczanie Twojego salda.</translation> + </message> + <message> <source>&Spend unconfirmed change</source> <translation>Wydaj niepotwierdzoną re&sztę</translation> </message> @@ -1067,10 +1077,6 @@ Adres: %4 <translation>&Minimalizuj do paska przy zegarku zamiast do paska zadań</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>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.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimalizuj przy zamknięciu</translation> </message> @@ -1083,10 +1089,6 @@ Adres: %4 <translation>Język &Użytkownika:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Można tu ustawić język interfejsu uzytkownika. Żeby ustawienie przyniosło skutek trzeba uruchomić ponownie Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Jednostka pokazywana przy kwocie:</translation> </message> @@ -1123,7 +1125,7 @@ Adres: %4 <translation>Wymagany restart programu, aby uaktywnić zmiany.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> + <source>Client will be shut down. Do you want to proceed?</source> <translation>Program zostanie wyłączony. Czy chcesz kontynuować?</translation> </message> <message> @@ -1209,10 +1211,6 @@ Adres: %4 <source>Current total balance in watch-only addresses</source> <translation>Łączna kwota na podglądanych adresach</translation> </message> - <message> - <source>out of sync</source> - <translation>nie zsynchronizowany</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1233,10 +1231,6 @@ Adres: %4 <translation>Sieć żądania płatności nie odpowiada sieci klienta.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Zażądanie płatności się przedawniło.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Żądanie płatności nie jest zainicjowane.</translation> </message> @@ -1257,14 +1251,50 @@ Adres: %4 <translation>URL pobrania żądania zapłaty jest nieprawidłowe: %1</translation> </message> <message> + <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source> + <translation>URI nie może zostać przetworzony! Może to być spowodowane nieprawidłowym adresem Bitcoin lub uszkodzonymi parametrami URI.</translation> + </message> + <message> + <source>Payment request file handling</source> + <translation>Przechwytywanie plików żądania płatności</translation> + </message> + <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>Plików żądania płatności nie może zostać odczytany. Mogło to być spowodowane nieprawidłowym plikiem żądania płatności.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Żądanie płatności upłynęło.</translation> + </message> + <message> + <source>Unverified payment requests to custom payment scripts are unsupported.</source> + <translation>Niezweryfikowane żądania płatności do własnych skryptów płatności są niewspierane.</translation> + </message> + <message> + <source>Invalid payment request.</source> + <translation>Nieprawidłowe żądanie płatności</translation> + </message> + <message> <source>Refund from %1</source> <translation>Zwrot z %1</translation> </message> <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>Żądanie płatności %1 jest zbyt duże (%2 bajtów, dozwolone %3 bajtów).</translation> + </message> + <message> + <source>Payment request DoS protection</source> + <translation>Zabezpieczenie żądania płatności przed atakiem DoS</translation> + </message> + <message> <source>Error communicating with %1: %2</source> <translation>Błąd komunikacji z %1 : %2</translation> </message> <message> + <source>Payment request cannot be parsed!</source> + <translation>Żądanie płatności nie może zostać przetworzone.</translation> + </message> + <message> <source>Bad response from server %1</source> <translation>Błędna odpowiedź z serwera %1</translation> </message> @@ -1280,8 +1310,12 @@ Adres: %4 <context> <name>PeerTableModel</name> <message> - <source>Address/Hostname</source> - <translation>Adres/Nazwa hosta</translation> + <source>User Agent</source> + <translation>Aplikacja kliencka</translation> + </message> + <message> + <source>Node/Service</source> + <translation>Węzeł/Usługi</translation> </message> <message> <source>Ping Time</source> @@ -1315,14 +1349,6 @@ Adres: %4 <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>SIEĆ</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>NIEZNANY</translation> - </message> - <message> <source>None</source> <translation>Żaden</translation> </message> @@ -1413,6 +1439,10 @@ Adres: %4 <translation>Aktualna liczba bloków</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Otwórz plik logowania debugowania Bitcoin Core z obecnego katalogu z danymi. Może to potrwać kilka sekund przy większych plikach.</translation> + </message> + <message> <source>Received</source> <translation>Otrzymane</translation> </message> @@ -1421,6 +1451,10 @@ Adres: %4 <translation>Wysłane</translation> </message> <message> + <source>&Peers</source> + <translation>&Węzły</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Wybierz węzeł żeby zobaczyć szczegóły.</translation> </message> @@ -1433,6 +1467,10 @@ Adres: %4 <translation>Wersja</translation> </message> <message> + <source>User Agent</source> + <translation>Aplikacja kliencka</translation> + </message> + <message> <source>Services</source> <translation>Usługi</translation> </message> @@ -1441,10 +1479,26 @@ Adres: %4 <translation>Początkowa wysokość</translation> </message> <message> + <source>Sync Height</source> + <translation>Zsynchronizowana wysokość</translation> + </message> + <message> + <source>Ban Score</source> + <translation>Punkty karne</translation> + </message> + <message> <source>Connection Time</source> <translation>Czas połączenia</translation> </message> <message> + <source>Last Send</source> + <translation>Ostatnio wysłano</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Ostatnio odebrano</translation> + </message> + <message> <source>Bytes Sent</source> <translation>Bajtów wysłano</translation> </message> @@ -1457,6 +1511,10 @@ Adres: %4 <translation>Czas odpowiedzi</translation> </message> <message> + <source>Time Offset</source> + <translation>Przesunięcie czasu</translation> + </message> + <message> <source>Last block time</source> <translation>Czas ostatniego bloku</translation> </message> @@ -1497,16 +1555,12 @@ Adres: %4 <translation>Plik logowania debugowania</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Otwórz plik logowania debugowania Bitcoin z obecnego katalogu z danymi. Może to potrwać kilka sekund przy większych plikach.</translation> - </message> - <message> <source>Clear console</source> <translation>Wyczyść konsolę</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Witam w konsoli Bitcoin RPC.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Witaj w konsoli Bitcoin Core RPC.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1576,6 +1630,10 @@ Adres: %4 <translation>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.</translation> </message> <message> + <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source> + <translation>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.</translation> + </message> + <message> <source>An optional label to associate with the new receiving address.</source> <translation>Opcjonalna etykieta do skojarzenia z nowym adresem odbiorczym.</translation> </message> @@ -1589,7 +1647,7 @@ Adres: %4 </message> <message> <source>Clear all fields of the form.</source> - <translation>Wyczyść pola formularza.</translation> + <translation>Wyczyść wszystkie pola formularza.</translation> </message> <message> <source>Clear</source> @@ -1707,7 +1765,7 @@ Adres: %4 </message> <message> <source>(no label)</source> - <translation>(bez etykiety)</translation> + <translation>(brak etykiety)</translation> </message> <message> <source>(no message)</source> @@ -1722,7 +1780,7 @@ Adres: %4 <name>SendCoinsDialog</name> <message> <source>Send Coins</source> - <translation>Wyślij Monety</translation> + <translation>Wyślij monety</translation> </message> <message> <source>Coin Control Features</source> @@ -1789,14 +1847,26 @@ Adres: %4 <translation>zwiń opcje opłaty</translation> </message> <message> - <source>Minimize</source> - <translation>Minimalizuj</translation> - </message> - <message> <source>per kilobyte</source> <translation>za kilobajt</translation> </message> <message> + <source>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.</source> + <translation>Jeżeli własna opłata zostanie ustawiona na 1000 satoshi, a transakcja będzie miała tylko 250 bajtów, to "za kilobajt" płaci tylko 250 satoshi, podczas gdy, "razem przynajmniej" płaci 1000 satoshi. Przy transakcjach większych niż kilobajt, w obu przypadkach płaci za każdy kilobajt.</translation> + </message> + <message> + <source>Hide</source> + <translation>Ukryj</translation> + </message> + <message> + <source>total at least</source> + <translation>razem przynajmniej</translation> + </message> + <message> + <source>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.</source> + <translation>Zapłacenie tylko minimalnej opłaty jest nadal wystarczające, dopóki jest mniejszy wolumen transakcji niż miejsca w blokach. Należy jednak mieć świadomość, że może skończyć się to niezatwierdzeniem nigdy transakcji, gdy jest większe zapotrzebowanie na transakcje bitcoina niż sieć może przetworzyć.</translation> + </message> + <message> <source>(read the tooltip)</source> <translation>(przeczytaj podpowiedź)</translation> </message> @@ -1805,6 +1875,10 @@ Adres: %4 <translation>Zalecane:</translation> </message> <message> + <source>Custom:</source> + <translation>Własna:</translation> + </message> + <message> <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> <translation>(Sprytne opłaty nie są jeszcze zainicjowane. Trwa to zwykle kilka bloków...)</translation> </message> @@ -1905,10 +1979,6 @@ Adres: %4 <translation>lub</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Adres odbiorcy jest nieprawidłowy, proszę poprawić.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Kwota do zapłacenia musi być większa od 0.</translation> </message> @@ -1921,10 +1991,6 @@ Adres: %4 <translation>Suma przekracza twoje saldo, gdy doliczymy %1 prowizji transakcyjnej.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Znaleziono powtórzony adres, można wysłać tylko raz na każdy adres podczas jednej operacji wysyłania.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Utworzenie transakcji nie powiodło się!</translation> </message> @@ -1933,20 +1999,36 @@ Adres: %4 <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> + <source>A fee higher than %1 is considered an absurdly high fee.</source> <translation>Opłata wyższa niż %1 jest uważana za szalenie wysoką.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Żądanie płatności upłynęło.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform></translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Płac tylko minimalna opłatę %1</translation> </message> <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Adres odbiorcy jest nieprawidłowy, proszę sprawić ponownie.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Znaleziono powtórzony adres, można wysłać tylko raz na każdy adres podczas jednej operacji wysyłania.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Ostrzeżenie: nieprawidłowy adres Bitcoin</translation> </message> <message> <source>(no label)</source> - <translation>(bez etykiety)</translation> + <translation>(brak etykiety)</translation> </message> <message> <source>Warning: Unknown change address</source> @@ -1985,13 +2067,17 @@ Adres: %4 </message> <message> <source>Choose previously used address</source> - <translation>Wybierz wcześniej użyty adres </translation> + <translation>Wybierz wcześniej użyty adres</translation> </message> <message> <source>This is a normal payment.</source> <translation>To jest standardowa płatność</translation> </message> <message> + <source>The Bitcoin address to send the payment to</source> + <translation>Adres Bitcoin gdzie wysłać płatność</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -2008,11 +2094,23 @@ Adres: %4 <translation>Usuń ten wpis</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>Opłata zostanie odjęta od kwoty wysyłane.Odbiorca otrzyma mniej niż bitcoins wpisz w polu kwoty. Jeśli wybrano kilku odbiorców, opłata jest podzielona równo.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>Odejmij od wysokości opłaty</translation> + </message> + <message> <source>Message:</source> <translation>Wiadomość:</translation> </message> <message> - <source>This is a verified payment request.</source> + <source>This is an unauthenticated payment request.</source> + <translation>To żądanie zapłaty nie zostało zweryfikowane.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> <translation>To żądanie zapłaty jest zweryfikowane.</translation> </message> <message> @@ -2020,8 +2118,8 @@ Adres: %4 <translation>Wprowadź etykietę dla tego adresu by dodać go do listy użytych adresów</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>To żądanie zapłaty nie zostało zweryfikowane.</translation> + <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source> + <translation>Wiadomość, która została dołączona do URI bitcoin:, która będzie przechowywana wraz z transakcją w celach informacyjnych. Uwaga: Ta wiadomość nie będzie rozsyłana w sieci Bitcoin.</translation> </message> <message> <source>Pay To:</source> @@ -2054,10 +2152,14 @@ Adres: %4 <translation>Podpi&sz Wiadomość</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> <translation>Możesz podpisywać wiadomości swoimi adresami aby udowodnić, że jesteś ich właścicielem. Uważaj, aby nie podpisywać niczego co wzbudza Twoje podejrzenia, ponieważ ktoś może stosować phishing próbując nakłonić Cię do ich podpisania. Akceptuj i podpisuj tylko w pełni zrozumiałe komunikaty i wiadomości.</translation> </message> <message> + <source>The Bitcoin address to sign the message with</source> + <translation>Adres Bitcoin, za pomocą którego podpisać wiadomość</translation> + </message> + <message> <source>Choose previously used address</source> <translation>Wybierz wcześniej użyty adres</translation> </message> @@ -2106,8 +2208,8 @@ Adres: %4 <translation>&Zweryfikuj wiadomość</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Wpisz adres podpisu, wiadomość (upewnij się, że dokładnie skopiujesz wszystkie zakończenia linii, spacje, tabulacje itp.) oraz podpis poniżej by sprawdzić wiadomość. Uważaj by nie dodać więcej do podpisu niż do samej podpisywanej wiadomości by uniknąć ataku man-in-the-middle (człowiek pośrodku)</translation> + <source>The Bitcoin address the message was signed with</source> + <translation>Adres Bitcoin, którym została podpisana wiadomość</translation> </message> <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> @@ -2224,7 +2326,7 @@ Adres: %4 </message> <message numerus="yes"> <source>, broadcast through %n node(s)</source> - <translation><numerusform>, przekazywany przez %n węzeł</numerusform><numerusform>, przekazywany przez %n węzły</numerusform><numerusform>, przekazywany przez %n węzłów</numerusform></translation> + <translation><numerusform>, przekazywany przez %n węzłów</numerusform><numerusform>, przekazywany przez %n węzłów</numerusform><numerusform>, przekazywany przez %n węzłów</numerusform></translation> </message> <message> <source>Date</source> @@ -2251,6 +2353,10 @@ Adres: %4 <translation>własny adres</translation> </message> <message> + <source>watch-only</source> + <translation>tylko-obserwowany</translation> + </message> + <message> <source>label</source> <translation>etykieta</translation> </message> @@ -2260,7 +2366,7 @@ Adres: %4 </message> <message numerus="yes"> <source>matures in %n more block(s)</source> - <translation><numerusform>potwierdzona przy %n bloku więcej</numerusform><numerusform>potwierdzona przy %n blokach więcej</numerusform><numerusform>potwierdzona przy %n blokach więcej</numerusform></translation> + <translation><numerusform>potwierdzona przy %n blokach więcej</numerusform><numerusform>potwierdzona przy %n blokach więcej</numerusform><numerusform>potwierdzona przy %n blokach więcej</numerusform></translation> </message> <message> <source>not accepted</source> @@ -2271,6 +2377,14 @@ Adres: %4 <translation>Debet</translation> </message> <message> + <source>Total debit</source> + <translation>Razem wychodzących</translation> + </message> + <message> + <source>Total credit</source> + <translation>Razem przychodzących</translation> + </message> + <message> <source>Transaction fee</source> <translation>Opłata transakcyjna</translation> </message> @@ -2328,7 +2442,7 @@ Adres: %4 </message> <message numerus="yes"> <source>Open for %n more block(s)</source> - <translation><numerusform>Otwórz dla %n bloku</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform></translation> + <translation><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform></translation> </message> <message> <source>unknown</source> @@ -2357,13 +2471,13 @@ Adres: %4 <translation>Typ</translation> </message> <message> - <source>Address</source> - <translation>Adres</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Niedojrzała (%1 potwierdzeń, będzie dostępna po %2)</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform></translation> + </message> <message> <source>Open until %1</source> <translation>Otwórz do %1</translation> @@ -2385,6 +2499,10 @@ Adres: %4 <translation>Offline</translation> </message> <message> + <source>Label</source> + <translation>Etykieta</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Niepotwierdzone:</translation> </message> @@ -2417,6 +2535,10 @@ Adres: %4 <translation>Wydobyto</translation> </message> <message> + <source>watch-only</source> + <translation>tylko-obserwowany</translation> + </message> + <message> <source>(n/a)</source> <translation>(brak)</translation> </message> @@ -2433,8 +2555,12 @@ Adres: %4 <translation>Rodzaj transakcji.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Adres docelowy transakcji.</translation> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Czy adres tylko-obserwowany jest lub nie użyty w tej transakcji.</translation> + </message> + <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Zdefiniowana przez użytkownika intencja/cel transakcji.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2528,6 +2654,10 @@ Adres: %4 <translation>Eksport historii transakcji</translation> </message> <message> + <source>Watch-only</source> + <translation>Tylko obserwowany</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Błąd przy próbie eksportu</translation> </message> @@ -2675,6 +2805,14 @@ Adres: %4 <translation>Skojarz z podanym adresem i nasłuchuj na nim. Użyj formatu [host]:port dla IPv6</translation> </message> <message> + <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> + <translation>Usuwa wszystkie transakcje w portfelu i tylko odtwarza te części z łańcucha bloków poprzez -rescan przy starcie</translation> + </message> + <message> + <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> + <translation>Rozprowadzane na licencji MIT, zobacz dołączony plik COPYING lub <http://www.opensource.org/licenses/mit-license.php>.</translation> + </message> + <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Wykonaj polecenie, kiedy transakcja portfela ulegnie zmianie (%s w poleceniu zostanie zastąpione przez TxID)</translation> </message> @@ -2711,6 +2849,10 @@ Adres: %4 <translation>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ą.</translation> </message> <message> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>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.</translation> + </message> + <message> <source>(default: 1)</source> <translation>(domyślnie: 1)</translation> </message> @@ -2743,10 +2885,6 @@ Adres: %4 <translation>Opcje debugowania/testowania:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Wykryj własny adres IP (domyślnie: 1 kiedy w trybie nasłuchu i brak -externalip )</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Nie ładuj portfela i wyłącz wywołania RPC portfela</translation> </message> @@ -2783,6 +2921,10 @@ Adres: %4 <translation>Próba nasłuchiwania na jakimkolwiek porcie nie powiodła się. Użyj -listen=0 jeśli tego chcesz.</translation> </message> <message> + <source>If <category> is not supplied, output all debugging information.</source> + <translation>Jeżeli <category> nie zostanie określona, wyświetl wszystkie informacje debugowania.</translation> + </message> + <message> <source>Importing...</source> <translation>Importowanie…</translation> </message> @@ -2803,8 +2945,8 @@ Adres: %4 <translation>Łącz z węzłami tylko w sieci <net> (ipv4, piv6 lub onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Odbuduj indeks łańcucha bloków z obecnych plików blk000??.dat</translation> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Tryb ograniczony jest niekompatybilny z -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2819,10 +2961,6 @@ Adres: %4 <translation>Określ plik portfela (w obrębie folderu danych)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Jest to przeznaczone dla narzędzi testowania regresji i rozwoju aplikacji.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Użyj UPnP do przekazania portu nasłuchu (domyślnie : %u)</translation> </message> @@ -2843,6 +2981,10 @@ Adres: %4 <translation>Opcje portfela:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Uwaga: Ta wersja jest przestarzała, wymagana jest aktualizacja!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Musisz przebudować bazę używając parametru -reindex aby zmienić -txindex</translation> </message> @@ -2859,10 +3001,22 @@ Adres: %4 <translation>Napotkano błąd podczas ustawiania adres RPC %s port %u dla nasłuchiwania: %s</translation> </message> <message> + <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> + <translation>Podepnij się do podanego adresu i dodawaj do białej listy węzły łączące się z nim. Użyj notacji [host]:port dla IPv6</translation> + </message> + <message> + <source>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)</source> + <translation>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)</translation> + </message> + <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>Nie można uzyskać blokady na katalogu z danymi %s. Rdzeń Bitcoin najprawdopodobniej jest już uruchomiony.</translation> </message> <message> + <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> + <translation>Twórz nowe pliki z domyślnymi dla systemu uprawnieniami, zamiast umask 077 (skuteczne tylko przy wyłączonej funkcjonalności portfela)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Błąd: Nasłuchiwanie połączeń przychodzących nie powiodło się (nasłuch zwrócił błąd %s)</translation> </message> @@ -2875,6 +3029,18 @@ Adres: %4 <translation>Uruchom polecenie przy otrzymaniu odpowiedniego powiadomienia lub gdy zobaczymy naprawdę długie rozgałęzienie (%s w poleceniu jest podstawiane za komunikat)</translation> </message> <message> + <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> + <translation>Opłaty (w BTC/Kb) mniejsze niż ta będą traktowane jako bez opłaty przy propagowaniu (domyślnie: %s)</translation> + </message> + <message> + <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> + <translation>Jeżeli nie ustawiono paytxfee, dołącz wystarczająca opłatę, aby transakcja mogła zostać zatwierdzona w ciągu średniej ilości n bloków (domyślnie: %u)</translation> + </message> + <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> + <translation>Niewłaściwa ilość dla -maxtxfee=<ilość>: '%s' (musi wynosić przynajmniej minimalną wielkość %s aby zapobiec utknięciu transakcji)</translation> + </message> + <message> <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> <translation>Maksymalny rozmiar danych w transakcji przekazującej dane które przekazujemy i wydobywamy (domyślnie: %u)</translation> </message> @@ -2883,10 +3049,6 @@ Adres: %4 <translation>Wyszukaj adresy węzłów wykorzystując zapytanie DNS, jeżeli masz mało adresów (domyślnie: 1 jeśli nie użyto -connect)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>Wymagaj wysokiego priorytetu dla przekazywania transakcji darmowych lub o niskiej opłacie (domyślnie:%u)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Ustaw maksymalny rozmiar transakcji o wysokim priorytecie/niskiej prowizji w bajtach (domyślnie: %d)</translation> </message> @@ -2895,14 +3057,74 @@ Adres: %4 <translation>Ustaw liczbę wątków dla generowania monet (-1 = wszystkie rdzenie, domyślnie: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Zbyt niska kwota transakcji do wysłania po odjęciu opłaty</translation> + </message> + <message> <source>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.</source> <translation>Program ten zawiera oprogramowanie stworzone przez OpenSSL Project do użycia w OpensSSL Toolkit <https://www.openssl.org/>, oprogramowanie kryptograficzne napisane przez Eric Young oraz oprogramowanie UPnP napisane przez Thomas Bernard.</translation> </message> <message> + <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: +%s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +The username and password MUST NOT be the same. +If the file does not exist, create it with owner-readable-only file permissions. +It is also recommended to set alertnotify so you are notified of problems; +for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com +</source> + <translation>Aby korzystać z bitcoind, lub opcji -server w bitcoin-qt, musisz ustawić opcję rpcpassword w pliku konfiguracyjnym: +%s +Zalecane jest użycie poniższego losowego hasła: +rpcuser=bitcoinrpc +rpcpassword=%s +(nie musisz pamiętać tego hasła) +Nazwa użytkownika i hasło NIE MOGĄ być takie same. +Jeżeli ten plik nie istnieje, utwórz go z uprawnieniami tylko-do-odczytu przez właściciela. +Zalecane jest także ustawienie opcji alertnotify, dzięki której będziesz powiadamiany o problemach; +na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com +</translation> + </message> + <message> <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> <translation>Ostrzeżenie: -matxfee jest ustawione bardzo wysokie! Tak wysokie opłaty mogą być zapłacone w jednej transakcji.</translation> </message> <message> + <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Ostrzeżenie: 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.</translation> + </message> + <message> + <source>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</source> + <translation>Węzły z białej listy nie mogą zostać zbanowane za ataki DoS, a ich transakcje będą zawsze przekazywane, nawet jeżeli będą znajdywać się już w pamięci, przydatne np. dla bramek płatniczych</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(domyślnie: %u)</translation> + </message> + <message> + <source>Accept public REST requests (default: %u)</source> + <translation>Akceptuj publiczne żądania REST (domyślnie: %u)</translation> + </message> + <message> + <source>Activating best chain...</source> + <translation>Aktywuje najlepszy łańcuch</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Nie można uruchomić z portfela w trybie ograniczonym.</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Nie można rozwiązać adresu -whitebind: '%s'</translation> + </message> + <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Wybierz folder danych przy starcie (domyślnie: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Połącz przez SOCKS5 proxy</translation> </message> @@ -2911,6 +3133,10 @@ Adres: %4 <translation>Copyright (C) 2009-%i The Bitcoin Core Developers</translation> </message> <message> + <source>Could not parse -rpcbind value %s as network address</source> + <translation>Nie można przetworzyć wartości -rpcbind %s jako adresu sieciowego</translation> + </message> + <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Błąd ładowania wallet.dat: Portfel wymaga nowszej wersji Bitcoin Core</translation> </message> @@ -2951,6 +3177,14 @@ Adres: %4 <translation>Nieprawidłowa kwota dla -paytxfee=<amount>: '%s' (musi być co najmniej %s)</translation> </message> <message> + <source>Invalid netmask specified in -whitelist: '%s'</source> + <translation>Nieprawidłowa maska sieci określona w -whitelist: '%s'</translation> + </message> + <message> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Przechowuj w pamięci maksymalnie <n> transakcji nie możliwych do połączenia (domyślnie: %u)</translation> + </message> + <message> <source>Node relay options:</source> <translation>Opcje przekaźnikowe węzła:</translation> </message> @@ -2963,12 +3197,16 @@ Adres: %4 <translation>Opcje serwera RPC:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Losowo ignoruje 1 z każdych <n> wiadomości sieciowych.</translation> + <source>RPC support for HTTP persistent connections (default: %d)</source> + <translation>Wsparcie RPC dla ciągłych połączeń HTTP (domyślnie: %d)</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Losowo miesza 1 z wszystkich <n> wiadomości sieciowych.</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Odbuduj indeks łańcucha bloków z obecnych plików blk000??.dat podczas ponownego uruchomienia</translation> + </message> + <message> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Odbieranie i wyświetlanie alertów sieci P2P (domyślnie: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -2979,10 +3217,22 @@ Adres: %4 <translation>Wyślij bez opłaty jeżeli to możliwe (domyślnie: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Ustaw certyfikaty główne SSL dla żądań płatności (domyślnie: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Ustaw Język, na przykład "pl_PL" (domyślnie: systemowy)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Pokaż wszystkie opcje odpluskwiania (użycie: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Pokazuj okno powitalne przy starcie (domyślnie: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Zmniejsz plik debug.log przy starcie programu (domyślnie: 1 jeśli nie użyto -debug)</translation> </message> @@ -2991,6 +3241,14 @@ Adres: %4 <translation>Podpisywanie transakcji nie powiodło się</translation> </message> <message> + <source>Start minimized</source> + <translation>Uruchom zminimalizowany</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Zbyt niska kwota transakcji by zapłacić opłatę</translation> + </message> + <message> <source>This is experimental software.</source> <translation>To oprogramowanie eksperymentalne.</translation> </message> @@ -3011,6 +3269,10 @@ Adres: %4 <translation>Transakcja zbyt duża</translation> </message> <message> + <source>UI Options:</source> + <translation>Opcje UI</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Nie można przywiązać do %s na tym komputerze (bind zwrócił błąd %s)</translation> </message> @@ -3031,10 +3293,6 @@ Adres: %4 <translation>Ostrzeżenie</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Uwaga: Ta wersja jest przestarzała, wymagana jest aktualizacja!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Uwaga: Zignorowano nieprawidłowy argument -benchmark, użyj -debug=bench.</translation> </message> @@ -3099,10 +3357,6 @@ Adres: %4 <translation>Jak dokładna jest weryfikacja bloków przy -checkblocks (0-4, domyślnie: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Loguj priorytety transakcji i opłaty na kB podczas kopania bloków (domyślnie: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Utrzymuj pełny indeks transakcji, używany przy wywołaniu RPC getrawtransaction (domyślnie: %u)</translation> </message> @@ -3111,16 +3365,28 @@ Adres: %4 <translation>Czas w sekundach, przez jaki nietrzymające się zasad węzły nie będą mogły ponownie się podłączyć (domyślnie: %u)</translation> </message> <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Wypuść informacje debugowania (domyślnie: %u, podanie <category> jest opcjonalne)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Użyj oddzielnego prozy SOCKS5 aby osiągnąć węzły w ukrytych usługach Tor (domyślnie: %s)</translation> + </message> + <message> <source>(default: %s)</source> <translation>(domyślnie: %s)</translation> </message> <message> - <source>Error loading wallet.dat</source> - <translation>Błąd ładowania wallet.dat</translation> + <source>Acceptable ciphers (default: %s)</source> + <translation>Akceptowane szyfry (domyślne: %s)</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Wymuś tryb bezpieczny (domyślnie: %u)</translation> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <translation>Zawsze wypytuj o adresy węzłów poprzez podejrzenie DNS (domyślnie: %u)</translation> + </message> + <message> + <source>Error loading wallet.dat</source> + <translation>Błąd ładowania wallet.dat</translation> </message> <message> <source>Generate coins (default: %u)</source> @@ -3139,10 +3405,6 @@ Adres: %4 <translation>Nieprawidłowy adres -proxy: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Ogranicz rozmiar pamięci podręcznej sygnatur do <n> wpisów (domyślnie: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Nasłuchuj połączeń JSON-RPC na <port> (domyślnie: %u lub testnet: %u)</translation> </message> @@ -3155,6 +3417,10 @@ Adres: %4 <translation>Utrzymuj maksymalnie <n> połączeń z węzłami (domyślnie: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Spraw by portfel dokonał transmisji transakcji</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Maksymalny bufor odbioru na połączenie, <n>*1000 bajtów (domyślnie: %u)</translation> </message> @@ -3163,10 +3429,6 @@ Adres: %4 <translation>Maksymalny bufor wysyłania na połączenie, <n>*1000 bajtów (domyślnie: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Akceptuj tylko łańcuch bloków zgodny z wbudowanymi punktami kontrolnymi (domyślnie: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Dołączaj znacznik czasu do logowania (domyślnie: %u)</translation> </message> @@ -3179,10 +3441,6 @@ Adres: %4 <translation>Przekazuj transakcje multisig inne niż P2SH (domyślnie: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Uruchom wątek do okresowego zapisywania portfela (domyślnie: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Plik certyfikatu serwera (domyślnie: %s)</translation> </message> @@ -3203,10 +3461,6 @@ Adres: %4 <translation>Ustaw liczbę wątków do obsługi RPC (domyślnie: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Ustaw flagę DB_PRIVATE w środowisku wallet db (domyślnie: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Wskaż plik konfiguracyjny (domyślnie: %s)</translation> </message> @@ -3223,10 +3477,6 @@ Adres: %4 <translation>Wydawaj niepotwierdzoną resztę podczas wysyłania transakcji (domyślnie: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Zatrzymaj po zaimportowaniu bloków z dysku (domyślnie: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Próg, po którym nastąpi rozłączenie węzłów nietrzymających się zasad (domyślnie: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index bc85f1f316..cd2a5a6323 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -1,4 +1,4 @@ -<TS language="pt_BR" version="2.1"> +<TS language="pt_BR" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -59,15 +59,15 @@ </message> <message> <source>Sending addresses</source> - <translation>Enviando endereços</translation> + <translation>Endereços para envios</translation> </message> <message> <source>Receiving addresses</source> - <translation>Recebendo endereços</translation> + <translation>Endereços de recebimento</translation> </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>Estes são os seus endereços Bitcoin para receber pagamentos. Você pode querer enviar um endereço diferente para cada remetente, para acompanhar quem está pagando.</translation> + <translation>Esses são seus endereços Bitcoin para enviar pagamentos. Certifique-se sempre da quantia e do destinatário antes de enviar moedas.</translation> </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> @@ -156,22 +156,22 @@ <translation>Alterar frase de segurança</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Digite a frase de segurança antiga e nova para a carteira.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Confirmar criptografia da carteira</translation> </message> <message> <source>Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!</source> - <translation>Atenção: Se você criptografar sua carteira e perder sua senha, você vai <b>perder todos os seus BITCOINS!</b></translation> + <translation>Atenção: Se você criptografar sua carteira e perder sua frase, você vai <b>perder todos os seus BITCOINS!</b></translation> </message> <message> <source>Are you sure you wish to encrypt your wallet?</source> <translation>Tem certeza de que deseja criptografar sua carteira?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -185,11 +185,11 @@ </message> <message> <source>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>.</source> - <translation>Digite a nova senha da carteira. <br/>Por favor utilize uma senha com <b>dez ou mais caracteres aleartórios</b>, ou <b>oito ou mais palavras</b>.</translation> + <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>O Bitcoin irá fechar agora para finalizar o processo de encriptação. Lembre-se de que encriptar sua carteira não protege totalmente suas bitcoins de serem roubadas por malwares que tenham infectado o seu computador.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Insira a frase antiga e a nova da carteira.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -224,7 +224,7 @@ <name>BitcoinGUI</name> <message> <source>Sign &message...</source> - <translation>&Assinar Mensagem...</translation> + <translation>&Assinar mensagem...</translation> </message> <message> <source>Synchronizing with network...</source> @@ -276,7 +276,7 @@ </message> <message> <source>&Backup Wallet...</source> - <translation>&Backup Carteira...</translation> + <translation>&Backup da carteira...</translation> </message> <message> <source>&Change Passphrase...</source> @@ -284,11 +284,11 @@ </message> <message> <source>&Sending addresses...</source> - <translation>Enviando endereço&s...</translation> + <translation>Endereço&s de envio...</translation> </message> <message> <source>&Receiving addresses...</source> - <translation>&Receber endereços...</translation> + <translation>Endereços de &recebimento...</translation> </message> <message> <source>Open &URI...</source> @@ -311,10 +311,6 @@ <translation>Enviar moedas para um endereço bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Modificar opções de configuração para bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Fazer cópia de segurança da carteira para uma outra localização</translation> </message> @@ -384,7 +380,7 @@ </message> <message> <source>&Help</source> - <translation>&Ajuda</translation> + <translation>A&juda</translation> </message> <message> <source>Tabs toolbar</source> @@ -403,6 +399,10 @@ <translation>&Sobre Bitcoin</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modificar opções de configuração do Bitcoin</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Mostrar a lista de endereços de envio e rótulos usados</translation> </message> @@ -483,6 +483,36 @@ <translation>Recuperando o atraso ...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Data: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Quantidade: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tipo: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Rótulo: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Endereço: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Transação enviada</translation> </message> @@ -491,17 +521,6 @@ <translation>Transação recebida</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Data: %1 -Quantidade: %2 -Tipo: %3 -Endereço: %4</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Carteira está <b>criptografada</b> e atualmente <b>desbloqueada</b></translation> </message> @@ -692,6 +711,18 @@ Endereço: %4</translation> <translation>nenhum</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Este texto fica vermelho se o tamanho da transação for maior que 1000 bytes.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Este texto fica vermelho se a prioridade é menor que "medio".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Este texto fica vermelho se qualquer destinatário receber uma quantidade menor que %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Pode variar +/- %1 satoshi(s) por entrada.</translation> </message> @@ -704,10 +735,6 @@ Endereço: %4</translation> <translation>não</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Esse marcador fica vermelho se a transação ultrapassar 1000 bytes.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Isso significa que uma taxa de pelo menos %1 por kB é necessária.</translation> </message> @@ -720,14 +747,6 @@ Endereço: %4</translation> <translation>Transações de alta prioridade são mais propensas a serem incluídas em um bloco.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Esse marcador fica vermelho se a prioridade for menor que "média".</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Esse marcador fica vermelho se qualquer destinatário receber uma quantia menor que %1</translation> - </message> - <message> <source>(no label)</source> <translation>(Sem rótulo)</translation> </message> @@ -848,30 +867,6 @@ Endereço: %4</translation> <source>command-line options</source> <translation>opções da linha de comando</translation> </message> - <message> - <source>UI options</source> - <translation>opções da UI</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Escolher língua, por exemplo "de_DE" (padrão: localização do sistema)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Inicializar minimizado</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Define certificados SSL root para requisição de pagamento (padrão: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostrar tela inicial ao ligar (padrão: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Escolha o diretório de dados na inicialização (padrão: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -954,14 +949,6 @@ Endereço: %4</translation> <translation>Principal</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Iniciar Bitcoin automaticamente após se logar no sistema.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>Iniciar Bitcoin no login do sistema</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Tamanho do banco de &dados do cache</translation> </message> @@ -986,6 +973,14 @@ Endereço: %4</translation> <translation>Endereço de IP do proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>A linguagem da interface do usuário pode ser alterada aqui. A mudança ocorrerá após o reinício do Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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 |.</translation> </message> @@ -1010,6 +1005,14 @@ Endereço: %4</translation> <translation>Rede</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Inicar automaticamente o Bitcoin ao logar no sistema.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Iniciar Bitcoin no login do sistema</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = automático, <0 = número de cores deixados livres)</translation> </message> @@ -1074,10 +1077,6 @@ Endereço: %4</translation> <translation>&Minimizar para a bandeja em vez da barra de tarefas.</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimizar em vez de sair do aplicativo quando a janela for fechada. Quando esta opção é escolhida, o aplicativo só será fechado selecionando Sair no menu Arquivo.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimizar ao sair</translation> </message> @@ -1090,10 +1089,6 @@ Endereço: %4</translation> <translation>&Linguagem da interface:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>A língua da interface com usuário pode ser escolhida aqui. Esta configuração só surtirá efeito após reiniciar o Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Unidade usada para mostrar quantidades:</translation> </message> @@ -1130,8 +1125,8 @@ Endereço: %4</translation> <translation>Reinicialização do aplicativo necessária para efetivar alterações.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>O aplicativo vai desligar, deseja continuar?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>O programa será encerrado. Deseja continuar?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1216,10 +1211,6 @@ Endereço: %4</translation> <source>Current total balance in watch-only addresses</source> <translation>Balanço total em endereços monitorados</translation> </message> - <message> - <source>out of sync</source> - <translation>fora de sincronia</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1236,10 +1227,6 @@ Endereço: %4</translation> <translation>Solicitação de pagamento rejeitada</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Solicitação de pagamento expirou.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Pedido de pagamento não é inicializado.</translation> </message> @@ -1264,14 +1251,26 @@ Endereço: %4</translation> <translation>Manipulação de arquivo de cobrança</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Pedido de pagamento expirado.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Cobrança não verificada para scripts de pagamento personalizados não é suportado.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Pedido de pagamento inválido.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Reembolso de %1</translation> </message> <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>Pedido de pagamento %1 é muito grande (%2 bytes, permitido %3 bytes).</translation> + </message> + <message> <source>Payment request DoS protection</source> <translation>Pagamento requer proteção DoS</translation> </message> @@ -1303,8 +1302,8 @@ Endereço: %4</translation> <translation>User Agent</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Endereço/Hostname</translation> + <source>Node/Service</source> + <translation>Nó/Serviço</translation> </message> <message> <source>Ping Time</source> @@ -1338,14 +1337,6 @@ Endereço: %4</translation> <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>REDE</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>DESCONHECIDO</translation> - </message> - <message> <source>None</source> <translation>Nenhum</translation> </message> @@ -1397,7 +1388,7 @@ Endereço: %4</translation> </message> <message> <source>Debug window</source> - <translation>Janela de debug</translation> + <translation>Janela de depuração</translation> </message> <message> <source>General</source> @@ -1436,6 +1427,10 @@ Endereço: %4</translation> <translation>Quantidade atual de blocos</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Abrir o arquivo de log de depuração do Bitcoin na pasta de dados atual. Isso pode demorar para arquivos grandes.</translation> + </message> + <message> <source>Received</source> <translation>Recebido</translation> </message> @@ -1544,16 +1539,12 @@ Endereço: %4</translation> <translation>Arquivo de log de Depuração</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Abrir o arquivo de log de depuração do Bitcoin do diretório atual de dados. Isso pode levar alguns segundos para arquivos de log grandes.</translation> - </message> - <message> <source>Clear console</source> <translation>Limpar console</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Bem-vindo ao console Bitcoin RPC.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Bem vindo ao console de RPC do Bitcoin.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1837,15 +1828,11 @@ Endereço: %4</translation> </message> <message> <source>Choose...</source> - <translation>Escolha:</translation> + <translation>Escolher</translation> </message> <message> - <source>Minimize</source> - <translation>Minimizar</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Se a taxa personalizada for definida em 1000 satoshis e a transação tiver somente 250 bytes, então "por kilobyte" somente paga 250 satoshis de taxa, enquanto "pelo menos" paga 1000 satoshis. Se a transação for maior que 1 kilobyte, ambos pagam por kilobyte.</translation> + <source>collapse fee-settings</source> + <translation>colapso Taxa de definições</translation> </message> <message> <source>per kilobyte</source> @@ -1856,6 +1843,10 @@ Endereço: %4</translation> <translation>Se a taxa personalizada for definida em 1000 satoshis e a transação tiver somente 250 bytes, então "por kilobyte" somente paga 250 satoshis de taxa, enquanto "pelo menos" paga 1000 satoshis. Se a transação for maior que 1 kilobyte, ambos pagam por kilobyte.</translation> </message> <message> + <source>Hide</source> + <translation>Ocultar</translation> + </message> + <message> <source>total at least</source> <translation>pelo menos</translation> </message> @@ -1976,10 +1967,6 @@ Endereço: %4</translation> <translation>ou</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>O endereço do destinatário não é válido, favor verificar.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>A quantidade a ser paga precisa ser maior que 0.</translation> </message> @@ -1992,10 +1979,6 @@ Endereço: %4</translation> <translation>O total excede seu saldo quando uma taxa de transação de %1 é incluída.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Endereço duplicado: pode-se enviar para cada endereço apenas uma vez por transação.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>A criação de transação falhou!</translation> </message> @@ -2004,16 +1987,28 @@ Endereço: %4</translation> <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> - <translation>Uma taxa acima de %1 é considerada uma taxa insanamente alta.</translation> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Uma taxa maior que %1 é considerada uma taxa absurdamente alto.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Pedido de pagamento expirado.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Confirmação estimada em %n bloco.</numerusform><numerusform>Confirmação estimada em %n blocos.</numerusform></translation> </message> <message> <source>Pay only the minimum fee of %1</source> <translation>Pagar somente a taxa mínima de %1</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Confirmação estimada em %1 bloco(s)</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>O endereço do destinatário é inválido. Favor confirmar.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Endereço duplicado encontrado: Endereços devem ser usados somente uma vez cada.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2087,12 +2082,24 @@ Endereço: %4</translation> <translation>Remover esta entrada</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>A taxa será deduzida da quantia sendo enviada. O beneficiario receberá menos bitcoins do que você colocou no campo de quantidade. Se varios beneficiarios estão selecionados, a taxa é dividida igualmente.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>&Retirar taxa da quantia</translation> + </message> + <message> <source>Message:</source> <translation>Mensagem:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Essa é cobrança verificada.</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Esta é uma cobrança não autenticada.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Esta é uma cobrança autenticada.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2103,10 +2110,6 @@ Endereço: %4</translation> <translation>A mensagem que foi anexada ao bitcoin: URI na qual será gravada na transação para sua referência. Nota: Essa mensagem não será gravada publicamente na rede Bitcoin.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Essa é uma cobrança não verificada.</translation> - </message> - <message> <source>Pay To:</source> <translation>Pague Para:</translation> </message> @@ -2123,7 +2126,7 @@ Endereço: %4</translation> </message> <message> <source>Do not shut down the computer until this window disappears.</source> - <translation>Não desligue o computador até esta janela desapareça.</translation> + <translation>Não desligue o computador até que esta janela desapareça.</translation> </message> </context> <context> @@ -2134,11 +2137,7 @@ Endereço: %4</translation> </message> <message> <source>&Sign Message</source> - <translation>&Assinar Mensagem</translation> - </message> - <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Você pode assinar mensagens com seus endereços para provar que você é o dono delas. Seja cuidadoso para não assinar algo vago, pois ataques de phishing podem tentar te enganar para dar sua assinatura de identidade para eles. Apenas assine afirmações completamente detalhadas com as quais você concorda.</translation> + <translation>&Assinar mensagem</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2178,7 +2177,7 @@ Endereço: %4</translation> </message> <message> <source>Sign &Message</source> - <translation>Assinar &Mensagem</translation> + <translation>Assinar &mensagem</translation> </message> <message> <source>Reset all sign message fields</source> @@ -2190,11 +2189,7 @@ Endereço: %4</translation> </message> <message> <source>&Verify Message</source> - <translation>&Verificar Mensagem</translation> - </message> - <message> - <source>Enter the signing 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.</source> - <translation>Forneça o endereço da assinatura, a mensagem (se assegure que você copiou quebras de linha, espaços, tabs, etc. exatamente) e a assinatura abaixo para verificar a mensagem. Cuidado para não ler mais na assinatura do que está escrito na mensagem propriamente, para evitar ser vítima de uma ataque do tipo "man-in-the-middle".</translation> + <translation>&Verificar mensagem</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2206,7 +2201,7 @@ Endereço: %4</translation> </message> <message> <source>Verify &Message</source> - <translation>Verificar &Mensagem</translation> + <translation>Verificar &mensagem</translation> </message> <message> <source>Reset all verify message fields</source> @@ -2214,7 +2209,7 @@ Endereço: %4</translation> </message> <message> <source>Click "Sign Message" to generate signature</source> - <translation>Clique em "Assinar Mensagem" para gerar a assinatura</translation> + <translation>Clique em "Assinar mensagem" para gerar a assinatura</translation> </message> <message> <source>The entered address is invalid.</source> @@ -2460,10 +2455,6 @@ Endereço: %4</translation> <translation>Tipo</translation> </message> <message> - <source>Address</source> - <translation>Endereço</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Recém-criado (%1 confirmações, disponível somente após %2)</translation> </message> @@ -2492,6 +2483,10 @@ Endereço: %4</translation> <translation>Offline</translation> </message> <message> + <source>Label</source> + <translation>Rótulo</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Não confirmado</translation> </message> @@ -2544,8 +2539,8 @@ Endereço: %4</translation> <translation>Tipo de transação.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Endereço de destino da transação.</translation> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Mostrar ou não endereços Bitcoin na lista de transações.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2759,7 +2754,7 @@ Endereço: %4</translation> </message> <message> <source>Specify data directory</source> - <translation>Especificar diretório de dados</translation> + <translation>Especificar o diretório de dados</translation> </message> <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> @@ -2798,16 +2793,12 @@ Endereço: %4</translation> <translation>Distribuido sob a licença MIT software license. Veja os termos em <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Entra no modo de teste de regressão, que usa uma cadeia especial onde os blocos podem ser resolvidos instantaneamente.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> - <translation>Executar comando quando uma transação da carteira mudar (%s no comando será substituído por TxID)</translation> + <translation>Executa um comando quando uma transação da carteira mudar (%s no comando será substituído por TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>Neste modo -genproclimit controla quantos blocos são gerados imediatamente.</translation> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Reduz o armazenamento requerido prunando (apagando) blocos antigos. Este modo desativa o suporte a carteira e é incompatível com -txindex. Aviso: Reverter essa opção requer re-baixar o blockchain inteiro. (padrão: 0 = disativado, >%u = Tamanho em mega para os arquivos de bloco)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2842,6 +2833,10 @@ Endereço: %4</translation> <translation>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.</translation> </message> <message> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Lista Branca pares de ligação da máscara de rede dado ou o endereço IP . Pode ser especificado várias vezes.</translation> + </message> + <message> <source>(default: 1)</source> <translation>(padrão: 1)</translation> </message> @@ -2859,7 +2854,7 @@ Endereço: %4</translation> </message> <message> <source>Connect only to the specified node(s)</source> - <translation>Conectar apenas a nó(s) específico(s)</translation> + <translation>Conectar apenas a cliente(s) específico(s)</translation> </message> <message> <source>Connection options:</source> @@ -2871,11 +2866,7 @@ Endereço: %4</translation> </message> <message> <source>Debugging/Testing options:</source> - <translation>Opções de Debug/Teste:</translation> - </message> - <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Descobrir os próprios endereços IP (padrão: 1 quando no modo listening e opção -externalip não estiver presente)</translation> + <translation>Opções de depuração/teste:</translation> </message> <message> <source>Do not load the wallet and disable wallet RPC calls</source> @@ -2915,7 +2906,7 @@ Endereço: %4</translation> </message> <message> <source>If <category> is not supplied, output all debugging information.</source> - <translation>Se <category> não for informada, logar toda informação de debug.</translation> + <translation>Se <category> não for informada, registrar toda informação de depuração.</translation> </message> <message> <source>Importing...</source> @@ -2938,8 +2929,12 @@ Endereço: %4</translation> <translation>Somente conectar a clientes na rede <net> (ipv4, ipv6 ou onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Reconstruir índice de blockchain a partir dos arquivos atuais blk000??.dat</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>O modo Prune não pode ser configurado com um valor negativo.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>O modo Prune é incompatível com -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2954,10 +2949,6 @@ Endereço: %4</translation> <translation>Especifique o arquivo da carteira (dentro do diretório de dados)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Isso é usado para testes de regressão e ferramentas de desenvolvimento.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Use UPnP para mapear a porta de entrada (padrão: %u)</translation> </message> @@ -2978,6 +2969,10 @@ Endereço: %4</translation> <translation>Opções da carteira:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Atenção: Essa versão está obsoleta, atualização necessária!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Você precisa reconstruir o banco de dados utilizando -reindex</translation> </message> @@ -2994,24 +2989,32 @@ Endereço: %4</translation> <translation>Um erro ocorreu enquanto configurando o endereço RPC %s porta %u para escuta: %s</translation> </message> <message> + <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> + <translation>Vincular ao endereço fornecido e sempre escutar nele. Use a notação [host]:port para IPv6</translation> + </message> + <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>Não foi possível obter acesso exclusivo ao diretório de dados %s. Provavelmente Bitcoin já está sendo executado.</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Descobrir o próprio IP (padrão: 1 enquanto aguardando conexões e sem -externalip ou -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Erro: Aceitar conexões de entrada falhou (retornou erro %s)</translation> </message> <message> <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source> - <translation>Executa o comando quando um alerta relevante é recebido ou vemos uma longa segregação (%s em cmd é substituído pela mensagem)</translation> + <translation>Executa um comando quando um alerta relevante é recebido ou vemos uma longa segregação (%s em cmd é substituído pela mensagem)</translation> </message> <message> <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> <translation>Taxas (em BTC/Kb) menores do que este valor são consideradas inexistentes para divulgação (padrão: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Taxas (em BTC/Kb) menores do que este valor são consideradas inexistentes para a criação da transação (padrão: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Prunagem configurada abaixo do mínimo de %d MB. Use um número maior.</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3042,10 +3045,26 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br </translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Você precisa reconstruir o banco de dados usando -reindex para sair do modo prune. Isso irá rebaixar todo o blockchain.</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(padrão: %u)</translation> + </message> + <message> + <source>Activating best chain...</source> + <translation>Ativando a melhor sequência...</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Impossível resolver endereço -whitebind: '%s'</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Escolha o diretório de dados na inicialização (padrão: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Connecte-se através de um proxy SOCKS5</translation> </message> @@ -3102,6 +3121,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Necessário informar uma porta com -whitebind: '%s'</translation> </message> <message> + <source>Node relay options:</source> + <translation>Opções de relé nó :</translation> + </message> + <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Opções RPC SSL: (veja o Bitcoin Wiki para instruções de configuração SSL)</translation> </message> @@ -3110,14 +3133,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Opções do servidor RPC:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Aleatoriamente descarta 1 em cada <n> mensagens da rede</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Aleatoriamente embaralha 1 em cada <n> mensagens da rede</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Mandar informação de trace/debug para o console em vez de para o arquivo debug.log</translation> </message> @@ -3126,8 +3141,20 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Enviar transação sem taxa, se possível (padrão: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Define certificados SSL root para requisição de pagamento (padrão: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Escolher língua, por exemplo "de_DE" (padrão: localização do sistema)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> - <translation>Exibir todas opções de debug (uso: --help -help-debug)</translation> + <translation>Exibir todas opções de depuração (uso: --help -help-debug)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Mostrar tela inicial ao ligar (padrão: 1)</translation> </message> <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> @@ -3138,6 +3165,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Assinatura de transação falhou</translation> </message> <message> + <source>Start minimized</source> + <translation>Inicializar minimizado</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Este é um software experimental.</translation> </message> @@ -3158,6 +3189,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Transação muito larga</translation> </message> <message> + <source>UI Options:</source> + <translation>Opções da interface:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Impossível se ligar a %s neste computador (bind retornou erro %s)</translation> </message> @@ -3178,10 +3213,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Atenção</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Atenção: Esta versão está obsoleta, atualização necessária!</translation> - </message> - <message> <source>Zapping all transactions from wallet...</source> <translation>Aniquilando todas as transações da carteira...</translation> </message> @@ -3199,7 +3230,7 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br </message> <message> <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source> - <translation>Executar comando quando o melhor bloco mudar (%s no comando será substituído pelo hash do bloco)</translation> + <translation>Executa um comando quando o melhor bloco mudar (%s no comando será substituído pelo hash do bloco)</translation> </message> <message> <source>Upgrade wallet to latest format</source> @@ -3215,7 +3246,7 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br </message> <message> <source>This help message</source> - <translation>Esta mensagem de ajuda</translation> + <translation>Exibe esta mensagem de ajuda</translation> </message> <message> <source>Allow DNS lookups for -addnode, -seednode and -connect</source> @@ -3234,34 +3265,42 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>(padrão: %s)</translation> </message> <message> - <source>Error loading wallet.dat</source> - <translation>Erro ao carregar wallet.dat</translation> + <source>Acceptable ciphers (default: %s)</source> + <translation>Cífras aceitas (padrão: %s)</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Forçar modo seguro (default: %u)</translation> + <source>Error loading wallet.dat</source> + <translation>Erro ao carregar wallet.dat</translation> </message> <message> <source>Generate coins (default: %u)</source> <translation>Gerar moedas (padrão: %u)</translation> </message> <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Quantos blocos devem ser checados ao iniciar (padrão: %u, 0 = todos)</translation> + </message> + <message> <source>Include IP addresses in debug output (default: %u)</source> - <translation>Incluir endereço IP na saída de debug (padrão: %u)</translation> + <translation>Incluir endereço IP na saída de depuração (padrão: %u)</translation> </message> <message> <source>Invalid -proxy address: '%s'</source> <translation>Endereço -proxy inválido: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Tamanho limite do cache de assinaturas de <n> entradas (padrão: %u)</translation> - </message> - <message> <source>Listen for connections on <port> (default: %u or testnet: %u)</source> <translation>Aguardar por conexões na porta <port> (padrão: %u ou testnet: %u)</translation> </message> <message> + <source>Prepend debug output with timestamp (default: %u)</source> + <translation>Adiciona timestamp como prefixo no debug (default: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <translation>Retransmitir P2SH não multisig (default: %u)</translation> + </message> + <message> <source>Server certificate file (default: %s)</source> <translation>Arquivo de certificado do servidor (padrão: %s)</translation> </message> @@ -3270,6 +3309,18 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Chave privada do servidor (padrão: %s)</translation> </message> <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Definir tamanho mínimo do bloco, em bytes (padrão: %u)</translation> + </message> + <message> + <source>Specify configuration file (default: %s)</source> + <translation>Especificar arquivo de configuração (padrão: %s)</translation> + </message> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Especificar tempo para desistência de conexões, em mili segundos (mínimo: 1, padrão: %d)</translation> + </message> + <message> <source>Specify pid file (default: %s)</source> <translation>Especificar aqrquivo pid (default: %s)</translation> </message> @@ -3299,7 +3350,7 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br </message> <message> <source>Add a node to connect to and attempt to keep the connection open</source> - <translation>Adicionar um nó com o qual se conectar e tentar manter a conexão ativa</translation> + <translation>Adicionar um cliente para se conectar e tentar manter a conexão ativa</translation> </message> <message> <source>Loading wallet...</source> diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index 1c1f62df44..7ac0a4fa5c 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -1,4 +1,4 @@ -<TS language="pt_PT" version="2.1"> +<TS language="pt_PT" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ <translation>Alterar frase de segurança</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Escreva a antiga frase de segurança da carteira, seguida da nova.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Confirmar encriptação da carteira</translation> </message> @@ -172,6 +168,10 @@ <translation>Tem a certeza que deseja encriptar a carteira?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -188,8 +188,8 @@ <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>O cliente Bitcoin 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.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Escreva a antiga frase de segurança da carteira, seguida da nova.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>Enviar moedas para um endereço bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Modificar opções de configuração para bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Faça uma cópia de segurança da carteira para outra localização</translation> </message> @@ -403,6 +399,10 @@ <translation>&Sobre o Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modificar opções de configuração de Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Mostrar a lista de rótulos e endereços de envio usados</translation> </message> @@ -431,6 +431,10 @@ <translation>Nenhuma fonte de blocos disponível...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Processado %n bloco do histórico de transações.</numerusform><numerusform>Processados %n blocos do histórico de transações.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation> </message> @@ -483,6 +487,36 @@ <translation>Recuperando o atraso...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Data: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Quantia: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tipo: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Rótulo: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Endereço: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Transação enviada</translation> </message> @@ -491,17 +525,6 @@ <translation>Transação recebida</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Data: %1 -Quantia: %2 -Tipo: %3 -Endereço: %4</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>A carteira está <b>encriptada</b> e atualmente <b>desbloqueada</b></translation> </message> @@ -692,6 +715,18 @@ Endereço: %4</translation> <translation>nenhum</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Este rótulo fica vermelho se o tamanho da transacção exceder os 1000 bytes.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Esta legenda fica vermelha se a prioridade for menor que "média".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Este rótulo fica vermelho se algum recipiente receber uma quantia menor que %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Pode variar +/- %1 satoshi(s) por entrada</translation> </message> @@ -704,10 +739,6 @@ Endereço: %4</translation> <translation>não</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Este rótulo fica vermelha se o tamanho da transacção exceder os 1000 bytes.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Isto significa que uma taxa de pelo menos %1 por kB é necessária.</translation> </message> @@ -720,14 +751,6 @@ Endereço: %4</translation> <translation>Transacções com uma prioridade mais alta têm uma maior probabilidade de serem incluídas num bloco.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Esta legenda fica vermelha, se a prioridade for menor que "média".</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Este rótulo fica vermelho se algum recipiente receber uma quantia menor que %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(sem rótulo)</translation> </message> @@ -848,30 +871,6 @@ Endereço: %4</translation> <source>command-line options</source> <translation>opções da linha de comandos</translation> </message> - <message> - <source>UI options</source> - <translation>Opções de Interface</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Definir linguagem, por exemplo "pt_PT" (por defeito: linguagem do sistema)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Iniciar minimizado</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Configurar certificados SSL root para pedido de pagamento (default: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostrar imagem ao iniciar (por defeito: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Escolha a pasta de dados ao iniciar (por defeito: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -954,14 +953,6 @@ Endereço: %4</translation> <translation>&Principal</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Começar o Bitcoin automaticamente ao iniciar sessão no sistema.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Começar o Bitcoin ao iniciar o sistema</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Tamanho da cache da base de &dados</translation> </message> @@ -986,6 +977,14 @@ Endereço: %4</translation> <translation>Endereço IP do proxy (p.ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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ú.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>A linguagem da interface do utilizador pode ser definida aqui. Esta definição entrará em efeito após reiniciar o Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>URLs de outrem (ex. um explorador de blocos) que aparece no separador de transações como itens do menu de contexto. %s do URL é substituído por hash de transação. Vários URLs são separados por barra vertical |.</translation> @@ -1011,6 +1010,14 @@ Endereço: %4</translation> <translation>&Rede</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Começar o Bitcoin Core automaticamente ao iniciar sessão no sistema.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Começar o Bitcoin Core ao iniciar o sistema</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = Deixar essa quantidade de núcleos livre)</translation> </message> @@ -1075,10 +1082,6 @@ Endereço: %4</translation> <translation>&Minimizar para a bandeja de sistema e não para a barra de ferramentas</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimize ao invés de sair da aplicação quando a janela é fechada. Com esta opção selecionada, a aplicação apenas será encerrada só quando escolher Sair da aplicação no menu.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimizar ao fechar</translation> </message> @@ -1091,10 +1094,6 @@ Endereço: %4</translation> <translation>&Linguagem da interface de utilizador:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>A linguagem da interface do utilizador pode ser definida aqui. Esta definição entrará em efeito após reiniciar o Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Unidade para mostrar quantias:</translation> </message> @@ -1131,8 +1130,8 @@ Endereço: %4</translation> <translation>É necessário reiniciar o cliente para ativar as alterações.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>O cliente será desligado, deseja continuar?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>O cliente será desligado. Deseja continuar?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1217,10 +1216,6 @@ Endereço: %4</translation> <source>Current total balance in watch-only addresses</source> <translation>Saldo disponivél em enderços modo-verificação</translation> </message> - <message> - <source>out of sync</source> - <translation>fora de sincronia</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1241,10 +1236,6 @@ Endereço: %4</translation> <translation>Rede de requisição de pagamento não corresponde com a rede do cliente.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Pedido de pagamento expirado.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Requisição de pagamento não iniciou.</translation> </message> @@ -1277,10 +1268,18 @@ Endereço: %4</translation> <translation>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.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Pedido de pagamento expirou.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Pedidos de pagamento não-verificados para scripts de pagamento personalizados não são suportados.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Pedido de pagamento inválido.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Reembolsar de %1</translation> </message> @@ -1320,8 +1319,8 @@ Endereço: %4</translation> <translation>Agente Usuário</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Endereço/Nome da Rede</translation> + <source>Node/Service</source> + <translation>Nó/Serviço</translation> </message> <message> <source>Ping Time</source> @@ -1355,14 +1354,6 @@ Endereço: %4</translation> <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>REDE</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>DESCONHECIDO</translation> - </message> - <message> <source>None</source> <translation>Nenhum</translation> </message> @@ -1561,16 +1552,12 @@ Endereço: %4</translation> <translation>Ficheiro de registo de depuração</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Abrir o ficheiro de registo de depuração da pasta de dados actual. Isto pode demorar alguns segundos para ficheiros de registo maiores.</translation> - </message> - <message> <source>Clear console</source> <translation>Limpar consola</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Bem-vindo à consola RPC Bitcoin.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Bem-vindo à consola RPC do Bitcoin Core.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1861,14 +1848,6 @@ Endereço: %4</translation> <translation>fechar definições-de custos</translation> </message> <message> - <source>Minimize</source> - <translation>Minimizar</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Se a taxa fixa for 1000 satoshis e a transação for somente 250 bytes, pagará somente 250 satoshis "por kilobyte" em custos se trasacionar "pelo menos" 1000 satoshis. Transações superiores a um kilobyte são cobradas por kilobyte.</translation> - </message> - <message> <source>per kilobyte</source> <translation>por kilobyte</translation> </message> @@ -1877,6 +1856,10 @@ Endereço: %4</translation> <translation>Se a taxa fixa for 1000 satoshis e a transação for somente 250 bytes, pagará somente 250 satoshis "por kilobyte" em custos se trasacionar "pelo menos" 1000 satoshis. Transações superiores a um kilobyte são cobradas por kilobyte.</translation> </message> <message> + <source>Hide</source> + <translation>Esconder</translation> + </message> + <message> <source>total at least</source> <translation>total minimo</translation> </message> @@ -1997,10 +1980,6 @@ Endereço: %4</translation> <translation>ou</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>O endereço de destino não é válido, por favor verifique.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>A quantia a pagar deverá ser maior que 0.</translation> </message> @@ -2013,10 +1992,6 @@ Endereço: %4</translation> <translation>O total excede o seu saldo quando a taxa de transação de %1 for incluída.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Endereço duplicado encontrado, apenas poderá enviar uma vez para cada endereço por cada operação de envio.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Erro: A criação da transação falhou! </translation> </message> @@ -2025,18 +2000,14 @@ Endereço: %4</translation> <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> - <translation>Uma taxa superior a %1 é considerada muito alta.</translation> + <source>Payment request expired.</source> + <translation>Pedido de pagamento expirou.</translation> </message> <message> <source>Pay only the minimum fee of %1</source> <translation>Pagar somente a taxa minima de %1</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Confirmação deverá começar dentro de %1 bloco(s).</translation> - </message> - <message> <source>Warning: Invalid Bitcoin address</source> <translation>Aviso: Endereço Bitcoin inválido</translation> </message> @@ -2112,10 +2083,6 @@ Endereço: %4</translation> <translation>Mensagem:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Este é um pedido de pagamento verificado.</translation> - </message> - <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Introduza um rótulo para este endereço para o adicionar à sua lista de endereços usados</translation> </message> @@ -2124,10 +2091,6 @@ Endereço: %4</translation> <translation>Uma mensagem que estava anexada ao URI bitcoin: que será armazenada com a transação para sua referência. Nota: Esta mensagem não será enviada através da rede Bitcoin.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Este é um pedido de pagamento não-verificado.</translation> - </message> - <message> <source>Pay To:</source> <translation>Pagar a:</translation> </message> @@ -2158,10 +2121,6 @@ Endereço: %4</translation> <translation>&Assinar Mensagem</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>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.</translation> - </message> - <message> <source>The Bitcoin address to sign the message with</source> <translation>O endereço Bitcoin para designar a mensagem</translation> </message> @@ -2214,10 +2173,6 @@ Endereço: %4</translation> <translation>&Verificar Mensagem</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>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.</translation> - </message> - <message> <source>The Bitcoin address the message was signed with</source> <translation>O endereço Bitcoin com que a mensagem foi designada</translation> </message> @@ -2481,10 +2436,6 @@ Endereço: %4</translation> <translation>Tipo</translation> </message> <message> - <source>Address</source> - <translation>Endereço</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Imaturo (%1 confirmações, estará disponível após %2)</translation> </message> @@ -2513,6 +2464,10 @@ Endereço: %4</translation> <translation>Offline</translation> </message> <message> + <source>Label</source> + <translation>Rótulo</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Não confirmado:</translation> </message> @@ -2569,10 +2524,6 @@ Endereço: %4</translation> <translation>Desde que um endereço de modo-verificação faça parte ou não desta transação</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Endereço de destino da transação.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Quantia retirada ou adicionada ao saldo.</translation> </message> @@ -2823,18 +2774,10 @@ Endereço: %4</translation> <translation>Distribuido através da licença de software MIT, verifique o ficheiro anexado COPYING ou <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Entre no modo de teste de regressão, que usa uma cadeia especial cujos blocos podem ser resolvidos instantaneamente.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Executar comando quando uma das transações na carteira mudar (no comando, %s é substituído pelo ID da Transação)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>O modo -genproclimit controla quantos blocos são generados imediatamente.</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>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)</translation> </message> @@ -2903,10 +2846,6 @@ Endereço: %4</translation> <translation>Depuração/Opções teste:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Descobrir endereço IP próprio (padrão: 1 ao escutar sem -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Não carregar a carteira e desativar chamadas RPC de carteira.</translation> </message> @@ -2967,10 +2906,6 @@ Endereço: %4</translation> <translation>Somente conectar aos nodes na rede <net> (ipv4, ipv6 ou onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Reconstruir a cadeia de blocos a partir dos ficheiros blk000??.dat atuais</translation> - </message> - <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Definir o tamanho da cache de base de dados em megabytes (%d a %d, padrão: %d)</translation> </message> @@ -2983,10 +2918,6 @@ Endereço: %4</translation> <translation>Especifique ficheiro de carteira (dentro da pasta de dados)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Isto têm como fim a realização de testes de regressão para pools e desenvolvimento de aplicações.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Use UPnP para mapear a porto de escuta (default: %u)</translation> </message> @@ -3007,6 +2938,10 @@ Endereço: %4</translation> <translation>Opções da carteira:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Aviso: Esta versão está desatualizada; atualização necessária!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>É necessário reconstruir as bases de dados usando -reindex para mudar o -txindex</translation> </message> @@ -3039,6 +2974,26 @@ Endereço: %4</translation> <translation>Definir tamanho máximo de transações com alta-prioridade/baixa-taxa em bytes (por defeito: %d)</translation> </message> <message> + <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Atenção: 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.</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(por defeito: %u)</translation> + </message> + <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Escolha a pasta de dados ao iniciar (por defeito: 0)</translation> + </message> + <message> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>Copyright (C) 2009-%i Os Programadores do Bitcoin Core</translation> + </message> + <message> + <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> + <translation>Erro ao carregar wallet.dat: A Carteira requer uma versão mais recente do Bitcoin Core</translation> + </message> + <message> <source>Information</source> <translation>Informação</translation> </message> @@ -3055,6 +3010,18 @@ Endereço: %4</translation> <translation>Enviar informação de rastreio/depuração para a consola e não para o ficheiro debug.log</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Configurar certificados SSL root para pedido de pagamento (default: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Definir linguagem, por exemplo "pt_PT" (por defeito: linguagem do sistema)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Mostrar imagem ao iniciar (por defeito: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Encolher ficheiro debug.log ao iniciar o cliente (por defeito: 1 sem -debug definido)</translation> </message> @@ -3063,6 +3030,10 @@ Endereço: %4</translation> <translation>Falhou assinatura da transação</translation> </message> <message> + <source>Start minimized</source> + <translation>Iniciar minimizado</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Quantia da transação é muito baixa</translation> </message> @@ -3083,12 +3054,12 @@ Endereço: %4</translation> <translation>Nome de utilizador para ligações JSON-RPC</translation> </message> <message> - <source>Warning</source> - <translation>Aviso</translation> + <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source> + <translation>A Carteira precisou de ser reescrita: reinicie o Bitcoin Core para completar o processo</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Atenção: Esta versão está obsoleta, é necessário actualizar!</translation> + <source>Warning</source> + <translation>Aviso</translation> </message> <message> <source>Zapping all transactions from wallet...</source> @@ -3143,6 +3114,58 @@ Endereço: %4</translation> <translation>Endereço -proxy inválido: '%s'</translation> </message> <message> + <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> + <translation>Escutar por ligações JSON-RPC na porta <port> (por defeito: %u ou rede de testes: %u)</translation> + </message> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Escute ligações na porta <port> (por defeito: %u ou testnet: %u)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Manter no máximo <n> ligações a outros nós da rede (por defeito: %u)</translation> + </message> + <message> + <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> + <translation>Maximo armazenamento intermédio de recepção por ligação, <n>*1000 bytes (por defeito: %u)</translation> + </message> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <translation>Maximo armazenamento intermédio de envio por ligação, <n>*1000 bytes (por defeito: %u)</translation> + </message> + <message> + <source>Prepend debug output with timestamp (default: %u)</source> + <translation>Adicionar data e hora à informação de depuração (por defeito: %u)</translation> + </message> + <message> + <source>Server certificate file (default: %s)</source> + <translation>Ficheiro de certificado do servidor (por defeito: %s)</translation> + </message> + <message> + <source>Server private key (default: %s)</source> + <translation>Chave privada do servidor (por defeito: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Definir o tamanho da memória de chaves para <n> (por defeito: %u)</translation> + </message> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Definir tamanho minímo de um bloco em bytes (por defeito: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <translation>Defina o número de processos para servir as chamadas RPC (por defeito: %d)</translation> + </message> + <message> + <source>Specify configuration file (default: %s)</source> + <translation>Especificar ficheiro de configuração (por defeito: %s)</translation> + </message> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Especificar tempo de espera da ligação em milissegundos (mínimo 1, por defeito: %d)</translation> + </message> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Rede desconhecida especificada em -onlynet: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts index ab36ff5321..be24668536 100644 --- a/src/qt/locale/bitcoin_ro_RO.ts +++ b/src/qt/locale/bitcoin_ro_RO.ts @@ -1,4 +1,4 @@ -<TS language="ro_RO" version="2.1"> +<TS language="ro_RO" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ <translation>Schimbare frază de acces</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Introduceţi vechea şi noua parolă pentru portofel.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Confirmaţi criptarea portofelului</translation> </message> @@ -172,6 +168,10 @@ <translation>Sigur doriţi să criptaţi portofelul dvs.?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -188,8 +188,8 @@ <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>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.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Introduceţi vechea şi noua parolă pentru portofel.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>Trimite monede către o adresă Bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Modifică opţiunile de configurare pentru Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Creează o copie de rezervă a portofelului într-o locaţie diferită</translation> </message> @@ -403,6 +399,10 @@ <translation>&Despre Nucleul Bitcoin</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modifică opţiunile de configurare pentru Bitcoin</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Arată lista de adrese trimise şi etichetele folosite.</translation> </message> @@ -431,6 +431,10 @@ <translation>Nici o sursă de bloc disponibilă...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>S-a procesat %n bloc din istoricul tranzacţiilor.</numerusform><numerusform>S-au procesat %n blocuri din istoricul tranzacţiilor.</numerusform><numerusform>S-au procesat %n de blocuri din istoricul tranzacţiilor.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n oră</numerusform><numerusform>%n ore</numerusform><numerusform>%n ore</numerusform></translation> </message> @@ -478,35 +482,49 @@ <source>Up to date</source> <translation>Actualizat</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>S-a procesat %n bloc din istoricul tranzacţiilor.</numerusform><numerusform>S-au procesat %n blocuri din istoricul tranzacţiilor.</numerusform><numerusform>S-au procesat %n de blocuri din istoricul tranzacţiilor.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Se actualizează...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Tranzacţie expediată</translation> + <source>Date: %1 +</source> + <translation>Data: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Tranzacţie recepţionată</translation> + <source>Amount: %1 +</source> + <translation>Sumă: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Data: %1 -Suma: %2 -Tipul: %3 -Adresa: %4 + <translation>Tip: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Etichetă: %1 </translation> </message> <message> + <source>Address: %1 +</source> + <translation>Adresă: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Tranzacţie expediată</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Tranzacţie recepţionată</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Portofelul este <b>criptat</b> iar în momentul de faţă este <b>deblocat</b></translation> </message> @@ -693,6 +711,18 @@ Adresa: %4 <translation>nimic</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Această etichetă devine roşie în cazul în care dimensiunea tranzacţiei este mai mare de 1000 de octeţi.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Această etichetă devine roşie dacă prioritatea e mai mică decît "medie".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Această etichetă devine roşie, dacă orice beneficiar primeşte o sumă mai mică decât %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Poate varia +/- %1 satoshi pentru fiecare intrare.</translation> </message> @@ -705,10 +735,6 @@ Adresa: %4 <translation>nu</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Această etichetă devine roşie, în cazul în care dimensiunea tranzacţiei este mai mare de 1000 de octeţi.</translation> - </message> - <message> <source>Can vary +/- 1 byte per input.</source> <translation>Poate varia +/- 1 octet pentru fiecare intrare.</translation> </message> @@ -717,10 +743,6 @@ Adresa: %4 <translation>Tranzacţiile cu prioritate mai mare sînt mai susceptibile de fi incluse într-un bloc.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Această etichetă devine roşie dacă prioritatea e mai mică decît "medie".</translation> - </message> - <message> <source>(no label)</source> <translation>(fără etichetă)</translation> </message> @@ -841,30 +863,6 @@ Adresa: %4 <source>command-line options</source> <translation>Opţiuni linie de comandă</translation> </message> - <message> - <source>UI options</source> - <translation>Opţiuni UI</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Setează limba, de exemplu: "de_DE" (implicit: sistem local)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Începe minimizat</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Setare rădăcină certificat SSL pentru cerere de plată (implicit: -sistem- )</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Afişează pe ecran splash la pornire (implicit: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Alege dosarul de date la pornire (implicit: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -943,14 +941,6 @@ Adresa: %4 <translation>Principal</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Porneşte automat Bitcoin după pornirea calculatorului.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>Porneşte Bitcoin la pornirea sistemului</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Mărimea bazei de &date cache</translation> </message> @@ -975,6 +965,14 @@ Adresa: %4 <translation>Adresa IP a serverului proxy (de exemplu: IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Limba interfeţei utilizatorului poate fi setată aici. Această setare va avea efect după repornirea Nucleului Bitcoin.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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ă |.</translation> </message> @@ -999,6 +997,10 @@ Adresa: %4 <translation>Reţea</translation> </message> <message> + <source>&Start Bitcoin Core on system login</source> + <translation>Porneşte Nucleul Bitcoin la pornirea sistemului</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = automat, <0 = lasă atîtea nuclee libere)</translation> </message> @@ -1063,10 +1065,6 @@ Adresa: %4 <translation>&Minimizare în tray în loc de taskbar</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Ascunde 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.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimizare fereastră în locul închiderii programului</translation> </message> @@ -1079,10 +1077,6 @@ Adresa: %4 <translation>&Limbă interfaţă utilizator</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Limba interfeţei utilizatorului poate fi setată aici. Această setare va avea efect după repornirea Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Unitatea de măsură pentru afişarea sumelor:</translation> </message> @@ -1119,8 +1113,8 @@ Adresa: %4 <translation>Este necesară repornirea clientului pentru a activa schimbările.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Clientul va fi închis, doriţi să continuaţi?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Clientul va fi închis. Doriţi să continuaţi?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1205,10 +1199,6 @@ Adresa: %4 <source>Current total balance in watch-only addresses</source> <translation>Soldul dvs. total în adresele doar-supraveghere</translation> </message> - <message> - <source>out of sync</source> - <translation>nesincronizat</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1229,10 +1219,6 @@ Adresa: %4 <translation>Cererea de plată din reţea nu se potriveşte cu clientul din reţea</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Cererea de plată a expirat.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Cererea de plată nu este iniţializată.</translation> </message> @@ -1253,6 +1239,10 @@ Adresa: %4 <translation>URL-ul cererii de plată preluat nu este valid: %1</translation> </message> <message> + <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source> + <translation>URI nu poate fi analizat! Acest lucru poate fi cauzat de o adresă Bitcoin nevalidă sau parametri URI deformaţi.</translation> + </message> + <message> <source>Payment request file handling</source> <translation>Manipulare fişier cerere de plată</translation> </message> @@ -1261,10 +1251,18 @@ Adresa: %4 <translation>Fişierul cerere de plată nu poate fi citit! Cauza poate fi un fişier cerere de plată nevalid.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Cererea de plată a expirat.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Cererile de plată neverificate prin script-uri personalizate de plată nu sînt suportate.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Cerere de plată nevalidă.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Rambursare de la %1</translation> </message> @@ -1304,10 +1302,6 @@ Adresa: %4 <translation>Agent utilizator</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Adresă/Nume gazdă</translation> - </message> - <message> <source>Ping Time</source> <translation>Timp ping</translation> </message> @@ -1339,14 +1333,6 @@ Adresa: %4 <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>REŢEA</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>NECUNOSCUT</translation> - </message> - <message> <source>None</source> <translation>Niciuna</translation> </message> @@ -1533,16 +1519,12 @@ Adresa: %4 <translation>Fişier jurnal depanare</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Deschide fişierul jurnal depanare din directorul curent. Aceasta poate dura cîteva secunde pentru fişierele mai mari.</translation> - </message> - <message> <source>Clear console</source> <translation>Curăţă consola</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Bun venit la consola bitcoin RPC.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Bun venit la consola Nucleului Bitcoin RPC.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1829,14 +1811,14 @@ Adresa: %4 <translation>Alegeţi...</translation> </message> <message> - <source>Minimize</source> - <translation>Minimizare</translation> - </message> - <message> <source>per kilobyte</source> <translation>per kilooctet</translation> </message> <message> + <source>Hide</source> + <translation>Ascunde</translation> + </message> + <message> <source>total at least</source> <translation>total cel puţin</translation> </message> @@ -1945,10 +1927,6 @@ Adresa: %4 <translation>sau</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Adresa destinatarului nu este validă, vă rugăm să o verificaţi.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Suma de plată trebuie să fie mai mare decît 0.</translation> </message> @@ -1961,10 +1939,6 @@ Adresa: %4 <translation>Totalul depăşeşte soldul contului dacă se include şi plata taxei de %1.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>S-a descoperit o adresă duplicat.Se poate trimite către fiecare adresă doar o singură dată per operaţiune.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Creare tranzacţie nereuşită!</translation> </message> @@ -1973,10 +1947,18 @@ Adresa: %4 <translation>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.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Cererea de plată a expirat.</translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Plăteşte doar taxa minimă de %1</translation> </message> <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Adresa destinatarului nu este validă, vă rugăm să o verificaţi.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Atenţie: Adresa bitcoin nevalidă!</translation> </message> @@ -2052,10 +2034,6 @@ Adresa: %4 <translation>Mesaj:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Aceasta este o cerere de plată verificată.</translation> - </message> - <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Introduceţi eticheta pentru ca această adresa să fie introdusă în lista de adrese folosite</translation> </message> @@ -2064,10 +2042,6 @@ Adresa: %4 <translation>un mesaj a fost ataşat la bitcoin: URI care va fi stocat cu tranzacţia pentru referinţa dvs. Notă: Acest mesaj nu va fi trimis către reţeaua bitcoin.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Aceasta este o cerere de plata neverificată.</translation> - </message> - <message> <source>Pay To:</source> <translation>Plăteşte către:</translation> </message> @@ -2098,10 +2072,6 @@ Adresa: %4 <translation>&Semnează mesaj</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Puteţi semna mesaje cu adresa dvs. pentru a demostra ca sînteti proprietarul lor. Aveţi grijă să nu semnaţi nimic vag, deoarece atacurile de tip phishing vă pot păcăli să le transferaţi identitatea. Semnaţi numai declaraţiile detaliate cu care sînteti de acord.</translation> - </message> - <message> <source>The Bitcoin address to sign the message with</source> <translation>Adresa cu care semnaţi mesajul</translation> </message> @@ -2154,10 +2124,6 @@ Adresa: %4 <translation>&Verifică mesaj</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Introduceţi adresa de semnatură, mesajul (asiguraţi-vă că aţi copiat spaţiile, taburile etc. exact) şi semnatura dedesubt pentru a verifica mesajul. Aveţi grijă să nu citiţi mai mult în semnatură decît mesajul în sine, pentru a evita să fiţi păcăliţi de un atac de tip man-in-the-middle.</translation> - </message> - <message> <source>The Bitcoin address the message was signed with</source> <translation>Introduceţi o adresă Bitcoin</translation> </message> @@ -2417,10 +2383,6 @@ Adresa: %4 <translation>Tip</translation> </message> <message> - <source>Address</source> - <translation>Adresă</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Imatur (%1 confirmări, va fi disponibil după %2)</translation> </message> @@ -2445,6 +2407,10 @@ Adresa: %4 <translation>Deconectat</translation> </message> <message> + <source>Label</source> + <translation>Etichetă</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Neconfirmat</translation> </message> @@ -2501,10 +2467,6 @@ Adresa: %4 <translation>Indiferent dacă sau nu o adresă doar-suăpraveghere este implicată în această tranzacţie.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Adresa de destinaţie a tranzacţiei.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Suma extrasă sau adăugată la sold.</translation> </message> @@ -2751,18 +2713,10 @@ Adresa: %4 <translation>Distribuit sub licenţa de programe MIT/X11, vezi fişierul însoţitor COPYING sau <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Iniţiază modul de test regresie, care foloseşte un lanţ special în care blocurile pot fi rezolvate instantaneu.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Execută comanda cînd o tranzacţie a portofelului se schimbă (%s în cmd este înlocuit de TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>În acest mod -genproclimit controlează cîte blocuri sînt generate imediat.</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>Setează numărul de thread-uri de verificare a script-urilor (%u la %d, 0 = auto, <0 = lasă atîtea nuclee libere, implicit: %d)</translation> </message> @@ -2827,10 +2781,6 @@ Adresa: %4 <translation>Opţiuni Depanare/Test:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Descoperă propria adresă IP (inţial: 1)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Nu încarcă portofelul şi dezactivează solicitările portofel RPC</translation> </message> @@ -2887,10 +2837,6 @@ Adresa: %4 <translation>Se conectează doar la noduri în reţeaua <net> (ipv4, ipv6 sau onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Reconstruirea indexului lanţului de bloc din fişierele actuale blk000???.dat</translation> - </message> - <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Setează mărimea bazei de date cache în megaocteţi (%d la %d, implicit: %d)</translation> </message> @@ -2903,10 +2849,6 @@ Adresa: %4 <translation>Specifică fişierul portofel (în dosarul de date)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Este folosită pentru programe de testare a regresiei în algoritmi şi dezvoltare de alte aplicaţii.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Foloseşte mapare UPnP pentru asculatere port (implicit: %u)</translation> </message> @@ -2963,6 +2905,10 @@ Adresa: %4 <translation>Acceptă cererile publice REST (implicit: %u)</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Alege dosarul de date la pornire (implicit: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Conectare prin proxy SOCKS5</translation> </message> @@ -3027,14 +2973,6 @@ Adresa: %4 <translation>RPC suportă pentru HTTP conexiuni persistente (implicit: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Aleator sccapă 1 din fiecare <n> mesaje ale reţelei</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Aleator aproximează 1 din fiecare <n> mesaje ale reţelei</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Trimite informaţiile trace/debug la consolă în locul fişierului debug.log</translation> </message> @@ -3043,10 +2981,22 @@ Adresa: %4 <translation>Trimitere tranzacţii ca tranzacţii taxă-zero dacă este posibil (implicit: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Setare rădăcină certificat SSL pentru cerere de plată (implicit: -sistem- )</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Setează limba, de exemplu: "de_DE" (implicit: sistem local)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Arată toate opţiunile de depanare (uz: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Afişează pe ecran splash la pornire (implicit: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Micşorează fişierul debug.log la pornirea clientului (implicit: 1 cînd nu se foloseşte -debug)</translation> </message> @@ -3055,6 +3005,10 @@ Adresa: %4 <translation>Nu s-a reuşit semnarea tranzacţiei</translation> </message> <message> + <source>Start minimized</source> + <translation>Începe minimizat</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Acesta este un program experimental.</translation> </message> @@ -3095,10 +3049,6 @@ Adresa: %4 <translation>Avertisment</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Atenţie: această versiune este depăşită, este necesară actualizarea!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Avertisment: Argument nesuportat -benchmark ignorat, folosiţi -debug=bench.</translation> </message> @@ -3155,10 +3105,6 @@ Adresa: %4 <translation>Eroare la încărcarea wallet.dat: Portofel corupt</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Goleşte baza de date a activităţii din memoria pool în jurnal pe disc la fiecare <n> megaocteţi (implicit: %u)</translation> - </message> - <message> <source>Output debugging information (default: %u, supplying <category> is optional)</source> <translation>Produce toate informaţiile de depanare (implicit: %u <category> furnizată este opţională)</translation> </message> @@ -3175,10 +3121,6 @@ Adresa: %4 <translation>Eroare la încărcarea wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Forţează mod sigur (implicit: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Generează monede (implicit: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index ab4a23cb9a..004208d345 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -1,4 +1,4 @@ -<TS language="ru" version="2.1"> +<TS language="ru" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -152,10 +152,6 @@ <translation>Сменить пароль</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Введите старый и новый пароль для бумажника.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Подтвердите шифрование бумажника</translation> </message> @@ -168,6 +164,10 @@ <translation>Вы уверены, что хотите зашифровать ваш бумажник?</translation> </message> <message> + <source>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.</source> + <translation>Сейчас программа закроется для завершения процесса шифрования. Помните, что шифрование вашего бумажника не может полностью защитить ваши биткоины от кражи с помощью инфицирования вашего компьютера вредоносным ПО.</translation> + </message> + <message> <source>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.</source> <translation>ВАЖНО: все предыдущие резервные копии вашего бумажника должны быть заменены новым зашифрованным файлом. В целях безопасности предыдущие резервные копии незашифрованного бумажника станут бесполезны, как только вы начнёте использовать новый зашифрованный бумажник.</translation> </message> @@ -184,8 +184,8 @@ <translation>Введите новый пароль бумажника.<br/>Используйте пароль, состоящий из <b>десяти или более случайных символов</b>, или <b>восьми или более слов</b>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Сейчас программа закроется для завершения процесса шифрования. Помните, что шифрование вашего бумажника не может полностью защитить ваши биткойны от кражи с помощью инфицирования вашего компьютера вредоносным ПО.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Введите старый и новый пароль для кошелька.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -307,10 +307,6 @@ <translation>Отправить монеты на указанный адрес Bitcoin</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Изменить параметры конфигурации Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Сделать резервную копию бумажника в другом месте</translation> </message> @@ -399,6 +395,10 @@ <translation>&О Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Изменить опции конфигурации Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Показать список использованных адресов и меток отправки</translation> </message> @@ -418,34 +418,18 @@ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> <translation>Показать помощь по Bitcoin Core и получить список доступных параметров командной строки.</translation> </message> - <message numerus="yes"> - <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n активное соединение с сетью</numerusform><numerusform>%n активных соединений с сетью</numerusform><numerusform>%n активных соединений с сетью Bitcoin</numerusform></translation> - </message> <message> <source>No block source available...</source> <translation>Источник блоков недоступен...</translation> </message> <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n час</numerusform><numerusform>%n часа</numerusform><numerusform>%n часов</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n день</numerusform><numerusform>%n дня</numerusform><numerusform>%n дней</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n week(s)</source> - <translation><numerusform>%n неделя</numerusform><numerusform>%n недели</numerusform><numerusform>%n недель</numerusform></translation> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Обработан %n блок истории транзакций.</numerusform><numerusform>Обработано %n блока истории транзакций.</numerusform><numerusform>Обработано %n блоков истории транзакций.</numerusform><numerusform>Обработано %n блоков истории транзакций.</numerusform></translation> </message> <message> <source>%1 and %2</source> <translation>%1 и %2</translation> </message> - <message numerus="yes"> - <source>%n year(s)</source> - <translation><numerusform>%n год</numerusform><numerusform>%n лет</numerusform><numerusform>%n года</numerusform></translation> - </message> <message> <source>%1 behind</source> <translation>%1 позади</translation> @@ -474,35 +458,49 @@ <source>Up to date</source> <translation>Синхронизировано</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>Обработан %n блок истории транзакций.</numerusform><numerusform>Обработано %n блока истории транзакций.</numerusform><numerusform>Обработано %n блоков истории транзакций.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Синхронизируется...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Исходящая транзакция</translation> + <source>Date: %1 +</source> + <translation>Дата: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Входящая транзакция</translation> + <source>Amount: %1 +</source> + <translation>Количество: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Дата: %1 -Сумма: %2 -Тип: %3 -Адрес: %4 + <translation>Тип: %1 </translation> </message> <message> + <source>Label: %1 +</source> + <translation>Метка: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Адрес: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Исходящая транзакция</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Входящая транзакция</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Бумажник <b>зашифрован</b> и в настоящее время <b>разблокирован</b></translation> </message> @@ -693,6 +691,18 @@ Address: %4 <translation>ничего</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Эта метка становится красной, если размер транзакции будет больше, чем 1000 байт.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Эта метка становится красной, если приоритет меньше, чем "среднее".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Эта метка становится красной, если любой из получателей принимает количество меньше, чем %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Может отличаться на +/- %1 сатоши на вход.</translation> </message> @@ -705,10 +715,6 @@ Address: %4 <translation>нет</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Эта пометка становится красной, если размер транзакции больше 1000 байт.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Это значит, что требуется комиссия как минимум %1 на КБ.</translation> </message> @@ -721,14 +727,6 @@ Address: %4 <translation>Транзакции с более высоким приоритетом будут вероятнее других включены в блок.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Эта пометка становится красной, если приоритет ниже, чем "средний".</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Эта пометка становится красной, если какой-либо из адресатов получает сумму менее %1.</translation> - </message> - <message> <source>(no label)</source> <translation>[нет метки]</translation> </message> @@ -849,30 +847,6 @@ Address: %4 <source>command-line options</source> <translation>параметры командной строки</translation> </message> - <message> - <source>UI options</source> - <translation>Настройки интерфейса</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Выберите язык, например "de_DE" (по умолчанию: как в системе)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Запускать свёрнутым</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Указать корневые SSL-сертификаты для запроса платежа (по умолчанию: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Показывать сплэш при запуске (по умолчанию: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Выбрать каталог данных при запуске (по умолчанию: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -912,15 +886,7 @@ Address: %4 <source>Error</source> <translation>Ошибка</translation> </message> - <message numerus="yes"> - <source>%n GB of free space available</source> - <translation><numerusform>%nГБ свободного места доступно</numerusform><numerusform>%nГБ свободного места доступно</numerusform><numerusform>%nГБ свободного места доступно</numerusform></translation> - </message> - <message numerus="yes"> - <source>(of %n GB needed)</source> - <translation><numerusform>(из необходимых %nГБ)</numerusform><numerusform>(из необходимых %nГБ)</numerusform><numerusform>(из необходимых %nГБ)</numerusform></translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -955,14 +921,6 @@ Address: %4 <translation>&Главная</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Автоматически запускать Bitcoin после входа в систему</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Запускать Bitcoin при входе в систему</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Размер кэша &БД</translation> </message> @@ -987,6 +945,14 @@ Address: %4 <translation>IP-адрес прокси (например IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Сворачивать вместо закрытия. Если данная опция будет выбрана — приложение закроется только после выбора соответствующего пункта в меню.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Здесь можно выбрать язык интерфейса. Настройки вступят в силу после перезапуска Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>Сторонние URL (например, block explorer), которые отображаются на вкладке транзакций как пункты контекстного меню. %s в URL заменяется хэшем транзакции. URL отделяются друг от друга вертикальной чертой |.</translation> </message> @@ -1011,6 +977,14 @@ Address: %4 <translation>&Сеть</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Автоматически запускать Bitcoin Core после входа в систему</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Запускать Bitcoin Core при входе в систему</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = автоматически, <0 = оставить столько незагруженных ядер)</translation> </message> @@ -1075,10 +1049,6 @@ Address: %4 <translation>&Cворачивать в системный лоток вместо панели задач</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Сворачивать вместо закрытия. Если данная опция будет выбрана — приложение закроется только после выбора соответствующего пункта в меню.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>С&ворачивать при закрытии</translation> </message> @@ -1091,10 +1061,6 @@ Address: %4 <translation>&Язык интерфейса:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Здесь можно выбрать язык интерфейса. Настройки вступят в силу после перезапуска Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Отображать суммы в единицах: </translation> </message> @@ -1131,8 +1097,8 @@ Address: %4 <translation>Для применения изменений требуется перезапуск клиента.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Клиент будет выключен, желаете продолжить?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Клиент будет выключен. Желаете продолжить?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1217,10 +1183,6 @@ Address: %4 <source>Current total balance in watch-only addresses</source> <translation>Текущий общий баланс на адресах наблюдения</translation> </message> - <message> - <source>out of sync</source> - <translation>не синхронизировано</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1241,10 +1203,6 @@ Address: %4 <translation>Сеть запроса платежа не совпадает с сетью клиента.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Запрос платежа просрочен.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Запрос платежа не инициализирован.</translation> </message> @@ -1277,10 +1235,18 @@ Address: %4 <translation>Файл запроса платежа не может быть прочитан! Обычно это происходит из-за неверного файла запроса платежа.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Запрос платежа просрочен.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Непроверенные запросы платежей с нестандартными платёжными сценариями не поддерживаются.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Неверный запрос платежа.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Возврат от %1</translation> </message> @@ -1320,8 +1286,8 @@ Address: %4 <translation>Юзер-агент</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Адрес/имя хоста</translation> + <source>Node/Service</source> + <translation>Узел/сервис</translation> </message> <message> <source>Ping Time</source> @@ -1355,14 +1321,6 @@ Address: %4 <translation>%1 с</translation> </message> <message> - <source>NETWORK</source> - <translation>СЕТЬ</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>НЕИЗВЕСТНЫЙ</translation> - </message> - <message> <source>None</source> <translation>Ничего</translation> </message> @@ -1453,6 +1411,10 @@ Address: %4 <translation>Текущее число блоков</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Открыть отладочный лог-файл Bitcoin Core из текущего каталога данных. Это может занять несколько секунд для больших лог-файлов.</translation> + </message> + <message> <source>Received</source> <translation>Получено</translation> </message> @@ -1521,6 +1483,10 @@ Address: %4 <translation>Время задержки</translation> </message> <message> + <source>Time Offset</source> + <translation>Смещение времени</translation> + </message> + <message> <source>Last block time</source> <translation>Время последнего блока</translation> </message> @@ -1561,16 +1527,12 @@ Address: %4 <translation>Отладочный лог-файл</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Открыть отладочный лог-файл Bitcoin из текущего каталога данных. Это может занять несколько секунд для больших лог-файлов.</translation> - </message> - <message> <source>Clear console</source> <translation>Очистить консоль</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Добро пожаловать в RPC-консоль Bitcoin.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Добро пожаловать в RPC-консоль Bitcoin Core.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1861,14 +1823,6 @@ Address: %4 <translation>Свернуть настройки комиссии</translation> </message> <message> - <source>Minimize</source> - <translation>Сворачивать</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Если комиссия установлена в 1000 сатоши, а транзакция составляет лишь 250 байт, тогда комиссия "на килобайт" составит 250 сатоши, а "как минимум" — 1000 сатоши. Для транзакций крупнее килобайта в обоих случаях будет использоваться платёж "на килобайт".</translation> - </message> - <message> <source>per kilobyte</source> <translation>за килобайт</translation> </message> @@ -1877,6 +1831,10 @@ Address: %4 <translation>Если комиссия установлена в 1000 сатоши, а транзакция составляет лишь 250 байт, тогда комиссия "на килобайт" составит 250 сатоши, а "всего как минимум" — 1000 сатоши. Для транзакций крупнее килобайта в обоих случаях будет использоваться платёж "на килобайт".</translation> </message> <message> + <source>Hide</source> + <translation>Скрыть</translation> + </message> + <message> <source>total at least</source> <translation>Итого как минимум</translation> </message> @@ -1997,10 +1955,6 @@ Address: %4 <translation>или</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Адрес получателя неверный, пожалуйста, перепроверьте.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Сумма для отправки должно быть больше 0.</translation> </message> @@ -2013,10 +1967,6 @@ Address: %4 <translation>Сумма превысит Ваш баланс, если комиссия в размере %1 будет добавлена к транзакции</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Обнаружен дублирующийся адрес. Отправка на один и тот же адрес возможна только один раз за одну операцию отправки</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Не удалось создать транзакцию!</translation> </message> @@ -2025,12 +1975,20 @@ Address: %4 <translation>Транзакция была отклонена! Такое может произойти, если некоторые монеты уже были потрачены, например, если Вы используете одну копию бумажника (wallet.dat), а монеты были потрачены из другой копии, но не были отмечены как потраченные в этой.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> + <source>A fee higher than %1 is considered an absurdly high fee.</source> <translation>Комиссия больше, чем %1, считается невероятно большой.</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Начало подтверждения ожидается через %1 блок(ов).</translation> + <source>Payment request expired.</source> + <translation>Запрос платежа просрочен.</translation> + </message> + <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Адрес получателя неверный. Пожалуйста, перепроверьте.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Обнаружен дублирующийся адрес: используйте каждый адрес только один раз.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2104,12 +2062,24 @@ Address: %4 <translation>Удалить эту запись</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>С отправляемой суммы будет удержана комиссия. Получателю придёт меньше биткоинов, чем вы вводите в поле количества. Если выбрано несколько получателей, комиссия распределяется поровну.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>Вычесть комиссию из суммы</translation> + </message> + <message> <source>Message:</source> <translation>Сообщение:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Это проверенный запрос платежа.</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Это неавторизованный запрос платежа.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Это авторизованный запрос платежа.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2120,10 +2090,6 @@ Address: %4 <translation>К bitcoin: URI было прикреплено сообщение, которое будет сохранено вместе с транзакцией для вашего сведения. Заметьте: сообщение не будет отправлено через сеть Bitcoin.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Это непроверенный запрос платежа.</translation> - </message> - <message> <source>Pay To:</source> <translation>Получатель:</translation> </message> @@ -2154,8 +2120,8 @@ Address: %4 <translation>&Подписать сообщение</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Вы можете подписывать сообщения своими адресами, чтобы доказать владение ими. Будьте осторожны, не подписывайте что-то неопределённое, так как фишинговые атаки могут обманным путём заставить вас подписать нежелательные сообщения. Подписывайте только те сообщения, с которыми вы согласны вплоть до мелочей.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Вы можете подписывать сообщения/соглашения своими адресами, чтобы доказать свою возможность получать биткоины на них. Будьте осторожны, не подписывайте что-то неопределённое или случайное, так как фишинговые атаки могут обманным путём заставить вас подписать нежелательные сообщения. Подписывайте только те сообщения, с которыми вы согласны вплоть до мелочей.</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2210,8 +2176,8 @@ Address: %4 <translation>&Проверить сообщение</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Введите ниже адрес для подписи, сообщение (убедитесь, что переводы строк, пробелы, табы и т.п. в точности скопированы) и подпись, чтобы проверить сообщение. Убедитесь, что не скопировали лишнего в подпись, по сравнению с самим подписываемым сообщением, чтобы не стать жертвой атаки "man-in-the-middle".</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Введите ниже адрес получателя, сообщение (убедитесь, что переводы строк, пробелы, табы и т.п. в точности скопированы) и подпись, чтобы проверить сообщение. Убедитесь, что не скопировали лишнего в подпись, по сравнению с самим подписываемым сообщением, чтобы не стать жертвой атаки "man-in-the-middle". Заметьте, что эта операция удостоверяет лишь авторство подписавшего, но не может удостоверить отправителя транзакции.</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2330,10 +2296,6 @@ Address: %4 <source>Status</source> <translation>Статус</translation> </message> - <message numerus="yes"> - <source>, broadcast through %n node(s)</source> - <translation><numerusform>, разослано через %n узел</numerusform><numerusform>, разослано через %n узла</numerusform><numerusform>, разослано через %n узлов</numerusform></translation> - </message> <message> <source>Date</source> <translation>Дата</translation> @@ -2370,10 +2332,6 @@ Address: %4 <source>Credit</source> <translation>Кредит</translation> </message> - <message numerus="yes"> - <source>matures in %n more block(s)</source> - <translation><numerusform>будет доступно через %n блок</numerusform><numerusform>будет доступно через %n блока</numerusform><numerusform>будет доступно через %n блоков</numerusform></translation> - </message> <message> <source>not accepted</source> <translation>не принято</translation> @@ -2446,10 +2404,6 @@ Address: %4 <source>, has not been successfully broadcast yet</source> <translation>, ещё не было успешно разослано</translation> </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>Открыто для ещё %n блока</numerusform><numerusform>Открыто для ещё %n блоков</numerusform><numerusform>Открыто для ещё %n блоков</numerusform></translation> - </message> <message> <source>unknown</source> <translation>неизвестно</translation> @@ -2477,17 +2431,9 @@ Address: %4 <translation>Тип</translation> </message> <message> - <source>Address</source> - <translation>Адрес</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Незрелый (%1 подтверждений, будет доступен после %2)</translation> </message> - <message numerus="yes"> - <source>Open for %n more block(s)</source> - <translation><numerusform>Открыто для ещё %n блока</numerusform><numerusform>Открыто для ещё %n блоков</numerusform><numerusform>Открыто для ещё %n блоков</numerusform></translation> - </message> <message> <source>Open until %1</source> <translation>Открыто до %1</translation> @@ -2509,6 +2455,10 @@ Address: %4 <translation>Нет активных соединений с сетью</translation> </message> <message> + <source>Label</source> + <translation>Метка</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Неподтверждено</translation> </message> @@ -2561,8 +2511,8 @@ Address: %4 <translation>Использовался ли в транзакции адрес для наблюдения.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Адрес назначения транзакции.</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Определяемое пользователем намерение/цель транзакции.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2815,16 +2765,16 @@ Address: %4 <translation>Распространяется под лицензией MIT, см. приложенный файл COPYING или <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Войти в режим тестирования на регрессии, в котором используется специальная цепь, где блоки находятся мгновенно.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Выполнить команду, когда меняется транзакция в бумажнике (%s в команде заменяется на TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>В этом режиме -genproclimit определяет, сколько блоков генерируется немедленно.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Максимальная сумма комиссий для одной транзакции в бумажнике; слишком низкое значение может вызвать прерывание больших транзакций (по умолчанию: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Уменьшить размер хранилища за счёт удаления (обрезания) старых блоков. Этот режим отключает поддержку бумажника и несовместим с -txindex. Внимание: переключение этой опции обратно потребует полной загрузки цепи блоков. (по умолчанию: 0 = отключить удаление блоков, >%u = целевой размер в Мб для файлов блоков)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2839,6 +2789,14 @@ Address: %4 <translation>Не удалось забиндиться на %s на этом компьютере. Возможно, Bitcoin Core уже запущен.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>ВНИМАНИЕ: сгенерировано ненормально большое число блоков, %d блоков получено за последние %d часов (ожидалось %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>ВНИМАНИЕ: проверьте сетевое подключение, получено %d блоков за последние %d часов (ожидалось %d)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Внимание: установлено очень большое значение -paytxfee. Это комиссия, которую вы заплатите при проведении транзакции.</translation> </message> @@ -2895,10 +2853,6 @@ Address: %4 <translation>Параметры отладки/тестирования:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Определить свой IP (по умолчанию: 1 при прослушивании и если не используется -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Не загружать бумажник и запретить обращения к нему через RPC</translation> </message> @@ -2959,8 +2913,12 @@ Address: %4 <translation>Соединяться только по сети <net> (ipv4, ipv6 или onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Перестроить индекс цепи блоков из текущих файлов blk000??.dat</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>Удаление блоков не может использовать отрицательное значение.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Режим удаления блоков несовместим с -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2975,10 +2933,6 @@ Address: %4 <translation>Укажите файл бумажника (внутри каталога данных)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Это рассчитано на инструменты регрессионного тестирования и разработку приложений.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Использовать UPnP для проброса порта (по умолчанию: %u)</translation> </message> @@ -2999,6 +2953,10 @@ Address: %4 <translation>Настройки бумажника:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Внимание: эта версия устарела; требуется обновление!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Вам необходимо пересобрать базы данных с помощью -reindex, чтобы изменить -txindex</translation> </message> @@ -3027,14 +2985,14 @@ Address: %4 <translation>Не удалось установить блокировку на каталог данных %s. Возможно, Bitcoin Core уже запущен.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Ограничить скорость передачи бесплатных транзакций до <n>*1000 байт в минуту (по умолчанию: %u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>Создавать новые файлы с системными правами по умолчанию вместо umask 077 (эффективно только при отключенном бумажнике)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Обнаруживать собственный IP адрес (по умолчанию: 1 при прослушивании и без -externalip или -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Ошибка: не удалось начать прослушивание входящих подключений (прослушивание вернуло ошибку %s)</translation> </message> @@ -3051,10 +3009,6 @@ Address: %4 <translation>Комиссии (в BTC/Кб) меньшие этого значения считаются нулевыми для трансляции (по умолчанию: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Комиссии (в BTC/Кб) меньшие этого значения считаются нулевыми для создания транзакции (по умолчанию: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Если paytxfee не задан, включить достаточную комиссию для подтверждения транзакции в среднем за n блоков (по умолчанию: %u)</translation> </message> @@ -3067,16 +3021,16 @@ Address: %4 <translation>Наибольший размер данных в носителе данных транзакций, которые мы передаем и генерируем (по умолчанию: %u)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>Максимальная сумма комиссий для одной транзакции в бумажнике, слишком низкое значение может вызвать прерывание больших транзакций (по умолчанию: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Удаление блоков выставлено ниже, чем минимум в %d Мб. Пожалуйста, используйте большее значение.</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Запрашивать адреса участников с помощью DNS, если адресов мало (по умолчанию: 1, если не указан -connect)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>Требовать высокий приоритет для пересылки бесплатных или низкокомиссионных транзакций (по умолчанию: %u)</translation> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Использовать случайные учётные данные для каждого прокси-подключения. Эта функция позволяет изолировать потоки Tor (по умолчанию: %u)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3087,6 +3041,10 @@ Address: %4 <translation>Задать число потоков генерации монет, если она включена (-1 = все ядра процессора, по умолчанию: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Сумма транзакции за вычетом комиссии слишком мала</translation> + </message> + <message> <source>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.</source> <translation>Этот продукт включает ПО, разработанное OpenSSL Project для использования в OpenSSL Toolkit <https://www.openssl.org/> и криптографическое ПО, написанное Eric Young и ПО для работы с UPnP, написанное Thomas Bernard.</translation> </message> @@ -3127,14 +3085,34 @@ rpcpassword=%s <translation>Участники из белого списка не могуть быть забанены за DoS, и их транзакции всегда транслируются, даже если они уже содержатся в памяти. Полезно, например, для шлюза.</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Вам необходимо пересобрать базу данных с помощью -reindex, чтобы вернуться к полному режиму. Это приведёт к перезагрузке всей цепи блоков</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(по умолчанию: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Принимать публичные REST-запросы (по умолчанию: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Активируется лучшая цепь...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Нельзя работать с бумажником в режиме с удалением блоков.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Не удаётся разрешить адрес в параметре -whitebind: '%s'</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Выбрать каталог данных при запуске (по умолчанию: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Подключаться через SOCKS5 прокси</translation> </message> @@ -3215,12 +3193,12 @@ rpcpassword=%s <translation>Поддержка RPC постоянных HTTP подключений (по умолчанию: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Случайно отбрасывать 1 из каждых <n> сетевых сообщений</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Перестроить при запуске индекс цепи блоков из текущих файлов blk000??.dat</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Случайно разбрасывать 1 из каждых <n> сетевых сообщений</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Получать и отображать P2P сетевые тревоги (по умолчанию: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3231,10 +3209,22 @@ rpcpassword=%s <translation>Осуществить транзакцию бесплатно, если возможно (по умолчанию: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Указать корневые SSL-сертификаты для запроса платежа (по умолчанию: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Выберите язык, например "de_DE" (по умолчанию: как в системе)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Показать все отладочные параметры (использование: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Показывать сплэш при запуске (по умолчанию: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Сжимать файл debug.log при запуске клиента (по умолчанию: 1, если нет -debug)</translation> </message> @@ -3243,6 +3233,14 @@ rpcpassword=%s <translation>Не удалось подписать транзакцию</translation> </message> <message> + <source>Start minimized</source> + <translation>Запускать свёрнутым</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Сумма транзакции слишком мала для уплаты комиссии</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Это экспериментальное ПО.</translation> </message> @@ -3263,6 +3261,10 @@ rpcpassword=%s <translation>Транзакция слишком большая</translation> </message> <message> + <source>UI Options:</source> + <translation>Настройки интерфейса:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Невозможно привязаться к %s на этом компьютере (bind вернул ошибку %s)</translation> </message> @@ -3283,10 +3285,6 @@ rpcpassword=%s <translation>Внимание</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Внимание: эта версия устарела, требуется обновление!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Внимание: неподдерживаемый аргумент -benchmark проигнорирован, используйте -debug=bench.</translation> </message> @@ -3347,18 +3345,10 @@ rpcpassword=%s <translation>(1 = сохранять метаданные транзакции: например, владельца аккаунта и информацию запроса платежа; 2 = отбросить метаданные)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Сбрасывать активность базы данных из памяти на диск каждые <n> мегабайт (по умолчанию: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Насколько тщательна проверка контрольных блоков -checkblocks (0-4, по умолчанию: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Записывать в лог приоритет транзакции и комиссию на килобайт во время добычи блоков (по умолчанию: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Держать полный индекс транзакций, используемый RPC-запросом getrawtransaction (по умолчанию: %u)</translation> </message> @@ -3387,18 +3377,10 @@ rpcpassword=%s <translation>Всегда запрашивать адреса участников с помощью DNS (по умолчанию: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Отключить безопасный режим, перекрыть реальное событие безопасного режима (по умолчанию: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Ошибка при загрузке wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Принудительный безопасный режим (по умолчанию: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Включить добычу монет (по умолчанию: %u)</translation> </message> @@ -3415,10 +3397,6 @@ rpcpassword=%s <translation>Неверный адрес -proxy: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Ограничить размер кэша подписей <n> записями (по умолчанию: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Прослушивать подключения JSON-RPC на <порту> (по умолчанию: %u или %u в тестовой сети)</translation> </message> @@ -3431,6 +3409,10 @@ rpcpassword=%s <translation>Поддерживать не более <n> подключений к узлам (по умолчанию: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Рассылать транзакции из бумажника</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Максимальный размер буфера приёма на соединение, <n>*1000 байт (по умолчанию: %u)</translation> </message> @@ -3439,10 +3421,6 @@ rpcpassword=%s <translation>Максимальный размер буфера отправки на соединение, <n>*1000 байт (по умолчанию: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Принимать цепь блоков, лишь если она соответствует встроенным контрольным точкам (по умолчанию: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Дописывать отметки времени к отладочному выводу (по умолчанию: %u)</translation> </message> @@ -3455,10 +3433,6 @@ rpcpassword=%s <translation>Транслировать не-P2SH мультиподпись (по умолчанию: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Запустить поток для периодического сохранения бумажника (по умолчанию: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Файл сертификата сервера (по умолчанию: %s)</translation> </message> @@ -3475,10 +3449,6 @@ rpcpassword=%s <translation>Задать число потоков выполнения запросов RPC (по умолчанию: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Установить флаг DB_PRIVATE в окружении базы данных бумажника (по умолчанию: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Указать конфигурационный файл (по умолчанию: %s)</translation> </message> @@ -3495,10 +3465,6 @@ rpcpassword=%s <translation>Тратить неподтвержденную сдачу при отправке транзакций (по умолчанию: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Остановиться после импорта блоков с диска (по умолчанию: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Порог для отключения неправильно ведущих себя узлов (по умолчанию: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_sah.ts b/src/qt/locale/bitcoin_sah.ts index 6cc17f480a..9ca08ee7da 100644 --- a/src/qt/locale/bitcoin_sah.ts +++ b/src/qt/locale/bitcoin_sah.ts @@ -1,4 +1,4 @@ -<TS language="sah" version="2.1"> +<TS language="sah" version="2.0"> <context> <name>AddressBookPage</name> </context> diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index a017c489b6..48d5a09142 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -1,4 +1,4 @@ -<TS language="sk" version="2.1"> +<TS language="sk" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ <translation>Zmena hesla</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Zadajte staré a nové heslo k peňaženke.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Potvrďte šifrovanie peňaženky</translation> </message> @@ -172,6 +168,10 @@ <translation>Ste si istí, že si želáte zašifrovať peňaženku?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -188,8 +188,8 @@ <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin sa teraz ukončí pre dokončenie procesu šifrovania. Pamätaj že šifrovanie peňaženky Ťa nemôže úplne ochrániť pred kráďežou bitcoinov pomocou škodlivého software.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Zadajte staré a nové heslo k peňaženke.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -276,7 +276,7 @@ </message> <message> <source>&Backup Wallet...</source> - <translation>&Backup peňaženku...</translation> + <translation>&Zálohovať peňaženku...</translation> </message> <message> <source>&Change Passphrase...</source> @@ -311,10 +311,6 @@ <translation>Poslať bitcoins na adresu</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Upraviť možnosti nastavenia pre bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Zálohovať peňaženku na iné miesto</translation> </message> @@ -332,7 +328,7 @@ </message> <message> <source>&Verify message...</source> - <translation>Overiť správu</translation> + <translation>O&veriť správu...</translation> </message> <message> <source>Bitcoin</source> @@ -396,13 +392,17 @@ </message> <message> <source>Request payments (generates QR codes and bitcoin: URIs)</source> - <translation>Vyžiadať platbu (vygeneruje QR kód a bitcoin: URI)</translation> + <translation>Vyžiadať platby (vygeneruje QR kódy a bitcoin: URI)</translation> </message> <message> <source>&About Bitcoin Core</source> <translation>O jadre Bitcoin</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Upraviť možnosti nastavenia pre Jadro Bitcoin</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Zobraziť zoznam použitých adries odosielateľa a ich popisy</translation> </message> @@ -431,6 +431,10 @@ <translation>Nedostupný zdroj blokov...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Spracovaných %n blok transakčnej histórie.</numerusform><numerusform>Spracovaných %n bloky transakčnej histórie.</numerusform><numerusform>Spracovaných %n blokov transakčnej histórie.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hodina</numerusform><numerusform>%n hodiny</numerusform><numerusform>%n hodín</numerusform></translation> </message> @@ -440,7 +444,7 @@ </message> <message numerus="yes"> <source>%n week(s)</source> - <translation><numerusform>%n týždňom</numerusform><numerusform>%n týždňami</numerusform><numerusform>%n týždňami</numerusform></translation> + <translation><numerusform>%n týždeň</numerusform><numerusform>%n týždne</numerusform><numerusform>%n týždňov</numerusform></translation> </message> <message> <source>%1 and %2</source> @@ -478,32 +482,47 @@ <source>Up to date</source> <translation>Aktualizovaný</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>Spracovaný %n blok transakčnej histórie.</numerusform><numerusform>Spracované %n bloky transakčnej histórie.</numerusform><numerusform>Spracovaných %n blokov transakčnej histórie.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Sťahujem...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Odoslané transakcie</translation> + <source>Date: %1 +</source> + <translation>Dátum: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Prijaté transakcie</translation> + <source>Amount: %1 +</source> + <translation>Suma: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Dátum: %1 -Suma: %2 -Typ: %3 -Adresa: %4</translation> + <translation>Typ: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Popis: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Adresa: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Odoslané transakcie</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Prijatá transakcia</translation> </message> <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> @@ -696,6 +715,18 @@ Adresa: %4</translation> <translation>žiadne</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Tento popis sčervenie ak veľkosť transakcie presiahne 1000 bajtov.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Tento popis sčervenie ak je priorita nižšia ako "stredná".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Tento popis sčervenie ak ktorýkoľvek príjemca dostane sumu menšiu ako %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Môže sa líšiť o +/- %1 satoshi pre každý vstup</translation> </message> @@ -708,10 +739,6 @@ Adresa: %4</translation> <translation>nie</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Tento popis zčervená ak veľkosť transakcie presiahne 1000 bytov.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>To znamená že požadovaný poplatok je aspoň %1 za kB.</translation> </message> @@ -724,14 +751,6 @@ Adresa: %4</translation> <translation>Transakcie s vysokou prioritou sa pravdepodobnejsie dostanú do bloku.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Tento popis zčervenie ak je priorita nižčia ako "medium".</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Tento popis zčervenie ak ktorýkoľvek príjemca dostane sumu menšiu ako %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(bez popisu)</translation> </message> @@ -852,30 +871,6 @@ Adresa: %4</translation> <source>command-line options</source> <translation>voľby príkazového riadku</translation> </message> - <message> - <source>UI options</source> - <translation>UI možnosti</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Nastaviť jazyk, napríklad "sk_SK" (predvolené: systémový)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Spustiť minimalizované</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Nastaviť koreňový certifikát pre výzvy na platbu (prednastavené: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Zobraziť splash screen pri spustení (predvolené: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Zvoľte dátový priečinok pri štarte (prednastavené: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -908,6 +903,10 @@ Adresa: %4</translation> <translation>Jadro Bitcoin</translation> </message> <message> + <source>Error: Specified data directory "%1" cannot be created.</source> + <translation>Chyba: Zadaný priečinok pre dáta "%1" nemôže byť vytvorený.</translation> + </message> + <message> <source>Error</source> <translation>Chyba</translation> </message> @@ -954,14 +953,6 @@ Adresa: %4</translation> <translation>&Hlavné</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Automaticky spustiť Bitcoin po zapnutí počítača</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Spustiť Bitcoin pri spustení systému správy okien</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Veľkosť vyrovnávacej pamäti &databázy</translation> </message> @@ -986,6 +977,14 @@ Adresa: %4</translation> <translation>IP adresy proxy (napr. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Tu sa dá nastaviť jazyk užívateľského rozhrania. Toto nastavenie bude účinné po reštartovaní Jadra Bitcoin.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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 |.</translation> </message> @@ -995,7 +994,7 @@ Adresa: %4</translation> </message> <message> <source>Active command-line options that override above options:</source> - <translation>Aktévne možnosti príkazového riadku ktoré prepíšu možnosti vyššie:</translation> + <translation>Aktívne možnosti príkazového riadku ktoré prepíšu možnosti vyššie:</translation> </message> <message> <source>Reset all client options to default.</source> @@ -1010,6 +1009,14 @@ Adresa: %4</translation> <translation>Sieť</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Automaticky spustiť Jadro Bitcoin po prihlásení do systému</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Spustiť Bitcoin pri spustení systému správy okien</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = nechať toľko jadier voľných)</translation> </message> @@ -1074,10 +1081,6 @@ Adresa: %4</translation> <translation>Zobraziť len ikonu na lište po minimalizovaní okna.</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimalizovat 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.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimalizovať pri zavretí</translation> </message> @@ -1090,10 +1093,6 @@ Adresa: %4</translation> <translation>Jazyk užívateľského rozhrania:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Tu sa dá nastaviť jazyk užívateľského rozhrania. Toto nastavenie bude účinné po reštartovaní Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Zobrazovať hodnoty v jednotkách:</translation> </message> @@ -1130,7 +1129,7 @@ Adresa: %4</translation> <translation>Reštart klienta potrebný pre aktivovanie zmien.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> + <source>Client will be shut down. Do you want to proceed?</source> <translation>Klient bude vypnutý, chcete pokračovať?</translation> </message> <message> @@ -1153,6 +1152,10 @@ Adresa: %4</translation> <translation>Zobrazené informácie môžu byť neaktuálne. Vaša peňaženka sa automaticky synchronizuje so sieťou Bitcoin po nadviazaní spojenia, ale tento proces ešte nie je ukončený.</translation> </message> <message> + <source>Watch-only:</source> + <translation>Iba sledované:</translation> + </message> + <message> <source>Available:</source> <translation>Disponibilné:</translation> </message> @@ -1189,12 +1192,28 @@ Adresa: %4</translation> <translation>Váš súčasný celkový zostatok</translation> </message> <message> + <source>Your current balance in watch-only addresses</source> + <translation>Váš celkový zostatok pre adresy ktoré sa iba sledujú</translation> + </message> + <message> + <source>Spendable:</source> + <translation>Použiteľné:</translation> + </message> + <message> <source>Recent transactions</source> <translation>Nedávne transakcie</translation> </message> <message> - <source>out of sync</source> - <translation>nesynchronizované</translation> + <source>Unconfirmed transactions to watch-only addresses</source> + <translation>Nepotvrdené transakcie pre adresy ktoré sa iba sledujú</translation> + </message> + <message> + <source>Mined balance in watch-only addresses that has not yet matured</source> + <translation>Vyťažená suma pre adresy ktoré sa iba sledujú ale ešte nie je dozretá</translation> + </message> + <message> + <source>Current total balance in watch-only addresses</source> + <translation>Aktuálny celkový zostatok pre adries ktoré sa iba sledujú</translation> </message> </context> <context> @@ -1208,6 +1227,18 @@ Adresa: %4</translation> <translation>Neplatná adresa platby %1</translation> </message> <message> + <source>Payment request rejected</source> + <translation>Požiadavka na platbu zamietnutá</translation> + </message> + <message> + <source>Payment request network doesn't match client network.</source> + <translation>Sieť požiadavky na platbu nie je zhodná so sieťou klienta.</translation> + </message> + <message> + <source>Payment request is not initialized.</source> + <translation>Požiadavka na platbu nie je inicializovaná</translation> + </message> + <message> <source>Requested payment amount of %1 is too small (considered dust).</source> <translation>Požadovaná platba sumy %1 je príliš malá (považovaná za prach).</translation> </message> @@ -1224,22 +1255,50 @@ Adresa: %4</translation> <translation>URL pre stiahnutie výzvy na zaplatenie je neplatné: %1</translation> </message> <message> + <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source> + <translation>URI sa nedá analyzovať! To môže byť spôsobené neplatnou Bitcoin adresou alebo zle upravenými vlastnosťami URI.</translation> + </message> + <message> <source>Payment request file handling</source> <translation>Obsluha súboru s požiadavkou na platbu</translation> </message> <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>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.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Vypršala platnosť požiadavky na platbu.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Program nepodporuje neoverené platobné výzvy na vlastná skripty.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Chybná požiadavka na platbu.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Vrátenie z %1</translation> </message> <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>Požiadavka na platbu %1 je príliš veľká (%2 bajtov, povolené je %3 bajtov).</translation> + </message> + <message> + <source>Payment request DoS protection</source> + <translation>Ochrana pred zahltením požiadavkami na platbu</translation> + </message> + <message> <source>Error communicating with %1: %2</source> <translation>Chyba komunikácie s %1: %2 </translation> </message> <message> + <source>Payment request cannot be parsed!</source> + <translation>Požiadavka na platbu nemôže byť analyzovaná!</translation> + </message> + <message> <source>Bad response from server %1</source> <translation>Zlá odpoveď zo servera %1</translation> </message> @@ -1259,8 +1318,8 @@ Adresa: %4</translation> <translation>Aplikácia</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Adresa/Názov počítača</translation> + <source>Node/Service</source> + <translation>Uzol/Služba</translation> </message> <message> <source>Ping Time</source> @@ -1278,6 +1337,10 @@ Adresa: %4</translation> <translation>Zadajte bitcoin adresu (napr. %1)</translation> </message> <message> + <source>%1 d</source> + <translation>%1 d</translation> + </message> + <message> <source>%1 h</source> <translation>%1 h</translation> </message> @@ -1286,6 +1349,14 @@ Adresa: %4</translation> <translation>%1 m</translation> </message> <message> + <source>%1 s</source> + <translation>%1 s</translation> + </message> + <message> + <source>None</source> + <translation>Žiadne</translation> + </message> + <message> <source>N/A</source> <translation>nie je k dispozícii</translation> </message> @@ -1372,6 +1443,10 @@ Adresa: %4</translation> <translation>Aktuálny počet blokov</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>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.</translation> + </message> + <message> <source>Received</source> <translation>Prijaté</translation> </message> @@ -1380,6 +1455,10 @@ Adresa: %4</translation> <translation>Odoslané</translation> </message> <message> + <source>&Peers</source> + <translation>&Partneri</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Vyberte počítač pre zobrazenie podrobností.</translation> </message> @@ -1404,10 +1483,26 @@ Adresa: %4</translation> <translation>Počiatočná výška</translation> </message> <message> + <source>Sync Height</source> + <translation>Synchronizovaná výška</translation> + </message> + <message> + <source>Ban Score</source> + <translation>Skóre zákazu</translation> + </message> + <message> <source>Connection Time</source> <translation>Dĺžka spojenia</translation> </message> <message> + <source>Last Send</source> + <translation>Posledné odoslanie</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Posledné prijatie</translation> + </message> + <message> <source>Bytes Sent</source> <translation>Odoslaných bajtov</translation> </message> @@ -1420,6 +1515,10 @@ Adresa: %4</translation> <translation>Čas odozvy</translation> </message> <message> + <source>Time Offset</source> + <translation>Časový posun</translation> + </message> + <message> <source>Last block time</source> <translation>Čas posledného bloku</translation> </message> @@ -1460,16 +1559,12 @@ Adresa: %4</translation> <translation>Súbor záznamu ladenia</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>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.</translation> - </message> - <message> <source>Clear console</source> <translation>Vymazať konzolu</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Vitajte v Bitcoin RPC konzole.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Vitajte v RPC konzole pre Jadro Bitcoin.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1496,6 +1591,14 @@ Adresa: %4</translation> <translation>%1 GB</translation> </message> <message> + <source>via %1</source> + <translation>cez %1</translation> + </message> + <message> + <source>never</source> + <translation>nikdy</translation> + </message> + <message> <source>Inbound</source> <translation>Prichádzajúce</translation> </message> @@ -1504,6 +1607,10 @@ Adresa: %4</translation> <translation>Odchádzajúce</translation> </message> <message> + <source>Unknown</source> + <translation>neznámy</translation> + </message> + <message> <source>Fetching...</source> <translation>Získava sa...</translation> </message> @@ -1740,16 +1847,12 @@ Adresa: %4</translation> <translation>Poplatok za transakciu:</translation> </message> <message> - <source>collapse fee-settings</source> - <translation>zbaliť nastavenia poplatkov</translation> - </message> - <message> - <source>Minimize</source> - <translation>Minimalizovať</translation> + <source>Choose...</source> + <translation>Zvoliť...</translation> </message> <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Ak je poplatok nastavený na 1000 satoshi a transakcia je veľká len 250 bajtov, potom "za kilobajt" zaplatí poplatok 250 satoshi, ale "aspoň" zaplatí 1000 satoshi. Pre transakcie väčšie ako kilobajt platia oba spôsoby za každý kilobajt.</translation> + <source>collapse fee-settings</source> + <translation>zbaliť nastavenia poplatkov</translation> </message> <message> <source>per kilobyte</source> @@ -1760,6 +1863,10 @@ Adresa: %4</translation> <translation>Ak je poplatok nastavený na 1000 satoshi a transakcia je veľká len 250 bajtov, potom "za kilobajt" zaplatí poplatok 250 satoshi, ale "spolu aspoň" zaplatí 1000 satoshi. Pre transakcie väčšie ako kilobajt platia oba spôsoby za každý kilobajt.</translation> </message> <message> + <source>Hide</source> + <translation>Skryť</translation> + </message> + <message> <source>total at least</source> <translation>spolu aspoň</translation> </message> @@ -1821,7 +1928,7 @@ Adresa: %4</translation> </message> <message> <source>Clear &All</source> - <translation>Zmazať &všetko</translation> + <translation>&Zmazať všetko</translation> </message> <message> <source>Balance:</source> @@ -1880,10 +1987,6 @@ Adresa: %4</translation> <translation>alebo</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Adresa príjemcu je neplatná, prosím, overte ju.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Suma na úhradu musí byť väčšia ako 0.</translation> </message> @@ -1896,10 +1999,6 @@ Adresa: %4</translation> <translation>Suma celkom prevyšuje Váš zostatok ak sú započítané %1 transakčné poplatky.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Duplikát adresy objavený, je možné poslať na každú adresu len raz v jednej odchádzajúcej transakcii.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Vytvorenie transakcie zlyhalo!</translation> </message> @@ -1908,14 +2007,26 @@ Adresa: %4</translation> <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> + <source>A fee higher than %1 is considered an absurdly high fee.</source> <translation>Poplatok vyšší ako %1 je považovaný za šialene vysoký.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Vypršala platnosť požiadavky na platbu.</translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Zaplatiť minimálny poplatok %1</translation> </message> <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Adresa príjemcu je neplatná. Prosím, overte ju.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Našla sa duplicitná adresa: každú adresu je možné použiť len raz.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Varovanie: Nesprávna Bitcoin adresa</translation> </message> @@ -1967,6 +2078,10 @@ Adresa: %4</translation> <translation>Toto je normálna platba.</translation> </message> <message> + <source>The Bitcoin address to send the payment to</source> + <translation>Zvoľte adresu kam poslať platbu</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1983,11 +2098,19 @@ Adresa: %4</translation> <translation>Odstrániť túto položku</translation> </message> <message> + <source>S&ubtract fee from amount</source> + <translation>Odpočítať poplatok od s&umy</translation> + </message> + <message> <source>Message:</source> <translation>Správa:</translation> </message> <message> - <source>This is a verified payment request.</source> + <source>This is an unauthenticated payment request.</source> + <translation>Toto je neoverená výzva k platbe.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> <translation>Toto je overená výzva k platbe.</translation> </message> <message> @@ -1999,10 +2122,6 @@ Adresa: %4</translation> <translation>Správa ktorá bola pripojená k bitcoin: URI a ktorá bude uložená s transakcou pre Vaše potreby. Poznámka: Táto správa nebude poslaná cez sieť Bitcoin.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Toto je neoverená výzva k platbe.</translation> - </message> - <message> <source>Pay To:</source> <translation>Platba pre:</translation> </message> @@ -2033,10 +2152,6 @@ Adresa: %4</translation> <translation>&Podpísať Správu</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Môžete podpísať správy svojou adresou a dokázať, že ju vlastníte. Buďte opatrní a podpíšte len prehlásenia s ktorými plne súhlasíte, nakoľko útoky typu "phishing" Vás môžu lákať k ich podpísaniu.</translation> - </message> - <message> <source>Choose previously used address</source> <translation>Vybrať predtým použitú adresu</translation> </message> @@ -2078,15 +2193,15 @@ Adresa: %4</translation> </message> <message> <source>Clear &All</source> - <translation>Zmazať &všetko</translation> + <translation>&Zmazať všetko</translation> </message> <message> <source>&Verify Message</source> - <translation>Overiť správu...</translation> + <translation>O&veriť správu...</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Vložte podpisovaciu adresu, správu (uistite sa, že kopírujete ukončenia riadkov, medzery, odrážky, atď. presne) a podpis pod to na overenie adresy. Buďte opatrní a nečítajte ako podpísané viac než je v samotnej podpísanej správe a môžete sa tak vyhnúť podvodu mitm útokom.</translation> + <source>The Bitcoin address the message was signed with</source> + <translation>Adresa Bitcoin, ktorou bola podpísaná správa</translation> </message> <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> @@ -2094,7 +2209,7 @@ Adresa: %4</translation> </message> <message> <source>Verify &Message</source> - <translation>Overiť správu</translation> + <translation>&Overiť správu</translation> </message> <message> <source>Reset all verify message fields</source> @@ -2201,6 +2316,10 @@ Adresa: %4</translation> <source>Status</source> <translation>Stav</translation> </message> + <message numerus="yes"> + <source>, broadcast through %n node(s)</source> + <translation><numerusform>, vysielať cez %n uzol</numerusform><numerusform>, vysielať cez %n uzle</numerusform><numerusform>, vysielať cez %n uzolov</numerusform></translation> + </message> <message> <source>Date</source> <translation>Dátum</translation> @@ -2226,6 +2345,10 @@ Adresa: %4</translation> <translation>vlastná adresa</translation> </message> <message> + <source>watch-only</source> + <translation>Iba sledovanie</translation> + </message> + <message> <source>label</source> <translation>popis</translation> </message> @@ -2242,6 +2365,14 @@ Adresa: %4</translation> <translation>Debet</translation> </message> <message> + <source>Total debit</source> + <translation>Debit spolu</translation> + </message> + <message> + <source>Total credit</source> + <translation>Kredit spolu</translation> + </message> + <message> <source>Transaction fee</source> <translation>Transakčný poplatok</translation> </message> @@ -2267,7 +2398,7 @@ Adresa: %4</translation> </message> <message> <source>Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source> - <translation>Vytvorené coins 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 reťaze, jeho stav sa zmení na "zamietnutý" a nebude sa dať minúť. Toto sa môže občas stať ak iná nóda vytvorí blok približne v tom istom čase.</translation> + <translation>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.</translation> </message> <message> <source>Debug information</source> @@ -2297,6 +2428,10 @@ Adresa: %4</translation> <source>, has not been successfully broadcast yet</source> <translation>, ešte nebola úspešne odoslaná</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Otvorené pre %n ďalší blok</numerusform><numerusform>Otvorené pre %n ďalšie bloky</numerusform><numerusform>Otvorené pre %n ďalších blokov</numerusform></translation> + </message> <message> <source>unknown</source> <translation>neznámy</translation> @@ -2324,13 +2459,13 @@ Adresa: %4</translation> <translation>Typ</translation> </message> <message> - <source>Address</source> - <translation>Adresa</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Nezrelé (%1 potvrdení, bude k dispozícii po %2)</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Otvorené pre %n ďalší blok</numerusform><numerusform>Otvorené pre %n ďalšie bloky</numerusform><numerusform>Otvorené pre %n ďalších blokov</numerusform></translation> + </message> <message> <source>Open until %1</source> <translation>Otvorené do %1</translation> @@ -2345,13 +2480,17 @@ Adresa: %4</translation> </message> <message> <source>Generated but not accepted</source> - <translation>Vypočítané ale neakceptované</translation> + <translation>Vygenerované ale neakceptované</translation> </message> <message> <source>Offline</source> <translation>Offline</translation> </message> <message> + <source>Label</source> + <translation>Popis</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Nepotvrdené</translation> </message> @@ -2381,7 +2520,11 @@ Adresa: %4</translation> </message> <message> <source>Mined</source> - <translation>Vyfárané</translation> + <translation>Vyťažené</translation> + </message> + <message> + <source>watch-only</source> + <translation>Iba sledovanie</translation> </message> <message> <source>(n/a)</source> @@ -2400,8 +2543,8 @@ Adresa: %4</translation> <translation>Typ transakcie.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Cieľová adresa transakcie.</translation> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Či sú ale nie sú, adresy iba na sledovanie zahrnuté v tejto transakcii.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2452,7 +2595,7 @@ Adresa: %4</translation> </message> <message> <source>Mined</source> - <translation>Vyfárané</translation> + <translation>Vyťažené</translation> </message> <message> <source>Other</source> @@ -2495,6 +2638,10 @@ Adresa: %4</translation> <translation>Exportovať históriu transakcií</translation> </message> <message> + <source>Watch-only</source> + <translation>Iba sledovanie</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Export zlyhal</translation> </message> @@ -2549,7 +2696,11 @@ Adresa: %4</translation> </context> <context> <name>UnitDisplayStatusBarControl</name> - </context> + <message> + <source>Unit to show amounts in. Click to select another unit.</source> + <translation>Jednotka pre zobrazovanie súm. Kliknite pre zvolenie inej jednotky.</translation> + </message> +</context> <context> <name>WalletFrame</name> <message> @@ -2638,16 +2789,16 @@ Adresa: %4</translation> <translation>Spojiť s danou adresou a vždy na nej počúvať. Použite zápis [host]:port pre IPv6</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Vojsť do režimu regresného testovania, ktorý používa špeciálnu reťaz v ktorej môžu byť bloky v okamihu vyriešené.</translation> + <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> + <translation>Vymazať všetky transakcie z peňaženky a pri spustení znova získať z reťazca blokov iba tie získané pomocou -rescan</translation> </message> <message> - <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> - <translation>Vykonaj príkaz keď sa zmení transakcia peňaženky (%s v príkaze je nahradená TxID)</translation> + <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> + <translation>Distribuované pod softvérovou licenciou MIT, viď sprievodný súbor COPYING alebo <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>V tomto režime -getproclimit kontroluje koľko blokov sa vytvorí okamžite.</translation> + <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> + <translation>Vykonaj príkaz keď sa zmení transakcia peňaženky (%s v príkaze je nahradená TxID)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2684,6 +2835,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>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.</translation> </message> <message> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Uzle na zoznam povolených, ktoré sa pripájajú z danej netmask alebo IP adresy. Môže byť zadané viac krát.</translation> + </message> + <message> <source>(default: 1)</source> <translation>(predvolené: 1)</translation> </message> @@ -2716,10 +2871,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Možnosti ladenia/testovania:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Zisti vlastnú IP adresu (predvolené: 1 pri počúvaní/listening a žiadnej -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Nenahrat peňaženku a zablokovať volania RPC.</translation> </message> @@ -2744,6 +2895,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Chyba otvárania databázy blokov</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Chyba: Nastala fatálna interná chyba. Pre podrobnosti pozrite debug.log</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Chyba: Málo miesta na disku!</translation> </message> @@ -2772,8 +2927,8 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Nedostatok kľúčových slov súboru.</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Znovu vytvoriť zoznam blokov zo súčasných blk000??.dat súborov</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>Pripojiť iba k uzlom v sieti <net> (ipv4, ipv6, alebo onion)</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2788,8 +2943,8 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Označ súbor peňaženky (v priečinku s dátami)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Toto je mienené nástrojom pre regresné testovania a vývoj programu.</translation> + <source>Use UPnP to map the listening port (default: %u)</source> + <translation>Použiť UPnP pre mapovanie počúvajúceho portu (predvolené: %u)</translation> </message> <message> <source>Verifying blocks...</source> @@ -2816,14 +2971,38 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Importuje bloky z externého súboru blk000??.dat</translation> </message> <message> + <source>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</source> + <translation>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</translation> + </message> + <message> + <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> + <translation>Pri nastavovaní RPC adresy %s na porte %u pre počúvanie došlo k chybe: %s</translation> + </message> + <message> + <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> + <translation>Spojiť s danou adresou a povolenými partnerskými zariadeniami ktoré sa tam pripájajú. Použite zápis [host]:port pre IPv6</translation> + </message> + <message> + <source>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)</source> + <translation>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)</translation> + </message> + <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>Neviem uzamknúť data adresár %s. Jadro Bitcoin je pravdepodobne už spustené.</translation> </message> <message> + <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> + <translation>Vytvoriť nové súbory z predvolenými systémovými právami, namiesto umask 077 (funguje iba z vypnutou funkcionalitou peňaženky)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Chyba: Počúvanie prichádzajúcich spojení zlyhalo (vrátená chyba je %s)</translation> </message> <message> + <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Chyba: Nájdený nepodporovaný argument -socks. Nastavenie SOCKS verzie nie je už možné, podporované sú už iba proxy SOCKS5.</translation> + </message> + <message> <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source> <translation>Vykonať príkaz po prijatí patričného varovania alebo uvidíme veľmi dlhé rozdvojenie siete (%s v cmd je nahradené správou)</translation> </message> @@ -2832,30 +3011,82 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Poplatky (v BTC/Kb) nižšie ako toľkoto sa považujú za nulové pri postupovaní transakcií (predvolené: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Poplatky (v BTC/Kb) nižšie ako toľkoto sa považujú za nulové pri vytváraní transakcií (predvolené: %s)</translation> + <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> + <translation>Ak nie je nastavené paytxfee, pridať dostatočný poplatok aby sa transakcia začala potvrdzovať priemerne v rámci bloku (predvolené: %u)</translation> + </message> + <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> + <translation>Neplatná suma pre -maxtxfee=<amount>: '%s' (aby sa transakcia nezasekla, minimálny prenosový poplatok musí byť aspoň %s)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</translation> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>Maximálna veľkosť dát v transakciách nosných dát, ktoré prenášame a ťažíme (predvolené: %u)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>Vyžadovať vysokú prioritu pre postúpenie transakcií s nízkymi poplatkami (predvolené:%u)</translation> + <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> + <translation>Dotaz na partnerské adresy pomocou vyhľadávania DNS v prípade nedostatku adries (predvolené: 1, pokiaľ -connect)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Nastaviť najväčšiu veľkosť vysoká-dôležitosť/nízke-poplatky transakcií v bajtoch (prednastavené: %d)</translation> </message> <message> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> + <translation>Nastaviť počet vlákien pre generáciu mincí (-1 = všetky jadrá, predvolené: %d)</translation> + </message> + <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> + <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>Upozornenie: -maxtxfee je nastavené príliš vysoko! Takto vysoké poplatky by mali byť zaplatené za jednu transakciu.</translation> + </message> + <message> + <source>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</source> + <translation>Uzle na zoznam povolených nemôžu byť DoS zakázané a ich transakcie vždy postúpené ďalej, aj v prípade, ak sú už pamäťovej fronte. Užitočné napr. pre brány</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(predvolené: %u)</translation> + </message> + <message> + <source>Accept public REST requests (default: %u)</source> + <translation>Akceptovať verejné REST žiadosti (predvolené: %u)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Nedá sa vyriešiť -whitebind adresa: '%s'</translation> + </message> + <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Zvoľte dátový priečinok pri štarte (prednastavené: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Pripojiť cez proxy server SOCKS5</translation> </message> <message> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>Autorské práva (C) 2009-%i Vývojári jadra Bitcoin</translation> + </message> + <message> + <source>Could not parse -rpcbind value %s as network address</source> + <translation>Nedá sa analyzovať -rpcbind hodnota %s ako sieťová adresa</translation> + </message> + <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Chyba pri čítaní wallet.dat: Peňaženka vyžaduje vyššiu verziu Jadra Bitcoin</translation> </message> <message> + <source>Error reading from database, shutting down.</source> + <translation>Chyba pri načítaní z databázy, ukončuje sa.</translation> + </message> + <message> + <source>Error: Unsupported argument -tor found, use -onion.</source> + <translation>Chyba: nájdený nepodporovaný argument -tor, použite -onion.</translation> + </message> + <message> <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> <translation>Poplatok (v BTC/kB), ktorý sa pridá k transakciám, ktoré odosielate (predvolený: %s)</translation> </message> @@ -2864,6 +3095,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Informácia</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Neplatná suma pre -maxtxfee=<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Neplatná suma pre -minrelaytxfee=<amount>: '%s'</translation> </message> @@ -2872,6 +3107,26 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Neplatná suma pre -mintxfee=<amount>: '%s'</translation> </message> <message> + <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source> + <translation>Neplatná suma pre -paytxfee=<amount>: '%s' (musí byť aspoň %s)</translation> + </message> + <message> + <source>Invalid netmask specified in -whitelist: '%s'</source> + <translation>Nadaná neplatná netmask vo -whitelist: '%s'</translation> + </message> + <message> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>V pamäti udržiavať najviac <n> nepotvrdených transakcií (predvolené: %u)</translation> + </message> + <message> + <source>Need to specify a port with -whitebind: '%s'</source> + <translation>Je potrebné zadať port s -whitebind: '%s'</translation> + </message> + <message> + <source>Node relay options:</source> + <translation>Prenosové možnosti uzla:</translation> + </message> + <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Možnosti RPC SSL: (Pozri v Bitcoin Wiki pokyny pre SSL nastavenie)</translation> </message> @@ -2880,12 +3135,12 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Možnosti servra RPC:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Náhodne zahadzuj 1 z každých <n> sieťových správ</translation> + <source>RPC support for HTTP persistent connections (default: %d)</source> + <translation>Podpora RPC pre trvalé HTTP spojenia (predvolené: %d)</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Náhodne premiešaj 1 z každých <n> sieťových správ</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Obdržať a zobraziť sieťové P2P varovania (predvolené: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -2896,10 +3151,22 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Poslať ako transakcie bez poplatku, ak je to možné (predvolené: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Nastaviť koreňový certifikát pre výzvy na platbu (prednastavené: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Nastaviť jazyk, napríklad "sk_SK" (predvolené: systémový)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Zobraziť všetky možnosti ladenia (použitie: --help --help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Zobraziť splash screen pri spustení (predvolené: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Zmenšiť debug.log pri spustení klienta (predvolené: 1 ak bez -debug)</translation> </message> @@ -2908,6 +3175,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Podpísanie správy zlyhalo</translation> </message> <message> + <source>Start minimized</source> + <translation>Spustiť minimalizované</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Toto je experimentálny softvér.</translation> </message> @@ -2928,6 +3199,14 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Transakcia príliš veľká</translation> </message> <message> + <source>UI Options:</source> + <translation>Možnosti používateľského rozhrania:</translation> + </message> + <message> + <source>Unable to bind to %s on this computer (bind returned error %s)</source> + <translation>Na tomto počítači sa nedá vytvoriť väzba %s (vytvorenie väzby vrátilo chybu %s)</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Skúsiť použiť UPnP pre mapovanie počúvajúceho portu (default: 1 when listening)</translation> </message> @@ -2940,8 +3219,12 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Upozornenie</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Upozornenie: Táto verzia je zastaraná, vyžaduje sa aktualizácia!</translation> + <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Upozornenie: Nepodporovaný argument -benchmark bol ignorovaný, použite -debug=bench.</translation> + </message> + <message> + <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Upozornenie: Nepodporovaný argument -debugnet bol ignorovaný, použite -debug=net.</translation> </message> <message> <source>Zapping all transactions from wallet...</source> @@ -2992,26 +3275,130 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Chyba načítania wallet.dat: Peňaženka je poškodená</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Zaznamenať prioritu transakcie a poplatok za kB pri ťažení blokov (predvolené: %u)</translation> + <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> + <translation>(1 = zachovať metaúdaje tx napr. vlastníka účtu a informácie o platobných príkazoch, 2 = zahodiť metaúdaje tx)</translation> + </message> + <message> + <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> + <translation>Ako dôkladné je -checkblocks overenie blokov (0-4, predvolené: %u)</translation> + </message> + <message> + <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> + <translation>Udržiavať kompletný transakčný index, využíva getrawtransaction rpc volanie (predvolené: %u)</translation> + </message> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Počet sekúnd, počas ktorých nepripájať zle správajúce sa uzle (predvolené: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Výstupné ladiace informácie (predvolené: %u, dodanie <category> je voliteľné)</translation> </message> <message> <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> <translation>Použiť samostatný SOCKS5 proxy server na dosiahnutie počítačov cez skryté služby Tor (predvolené: %s)</translation> </message> <message> + <source>(default: %s)</source> + <translation>(predvolené: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Prijateľné šifry (predvolené: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <translation>Vždy sa dotazovať adresy partnerských uzlov cez vyhľadávanie DNS (predvolené: %u)</translation> + </message> + <message> <source>Error loading wallet.dat</source> <translation>Chyba načítania wallet.dat</translation> </message> <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Koľko blokov overiť pri spustení (predvolené: %u, 0 = všetky)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>Zahrnúť IP adresy v ladiacom výstupe (predvolené: %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <translation>Neplatná adresa proxy: '%s'</translation> </message> <message> + <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> + <translation>Počúvať JSON-RPC pripojenia na <port> (predvolené: %u alebo testovacia sieť: %u)</translation> + </message> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Počúvať pripojenia na <port> (predvolené: %u alebo testovacia sieť: %u)</translation> + </message> + <message> <source>Maintain at most <n> connections to peers (default: %u)</source> <translation>Udržiavať najviac <n> spojení s inými počítačmi (predvolené: %u)</translation> </message> <message> + <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> + <translation>Maximálna prijímajúca medzipamäť pre pripojenie, <n>*1000 bajtov (predvolené: %u)</translation> + </message> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <translation>Maximálna odosielajúca medzipamäť pre pripojenie, <n>*1000 bajtov (predvolené: %u)</translation> + </message> + <message> + <source>Prepend debug output with timestamp (default: %u)</source> + <translation>Na začiatok pripojiť časovú známku k ladiacemu výstupu (predvolené: %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>Prenášať a ťažiť transakcie nosných dát (predvolené: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <translation>Prenášať non-P2SH multi-podpis (predvolené: %u)</translation> + </message> + <message> + <source>Server certificate file (default: %s)</source> + <translation>Certifikačný súbor servera (predvolené: %s)</translation> + </message> + <message> + <source>Server private key (default: %s)</source> + <translation>Privátny kľúč servera (predvolené: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Nastaviť veľkosť kľúča fronty na <n> (predvolené: %u)</translation> + </message> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Nastaviť minimálnu veľkosť bloku v bajtoch (predvolené: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <translation>Nastaviť počet vlákien na obsluhu RPC volaní (predvolené: %d)</translation> + </message> + <message> + <source>Specify configuration file (default: %s)</source> + <translation>Zadať konfiguračný súbor (predvolené: %s)</translation> + </message> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Zadajte časový limit pripojenia v milisekundách (minimum: 1, predvolené: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Zadať pid súbor (predvolené: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <translation>Minúť nepotvrdené zmenu pri posielaní transakcií (predvolené: %u)</translation> + </message> + <message> + <source>Threshold for disconnecting misbehaving peers (default: %u)</source> + <translation>Hranica pre odpájanie zle sa správajúcim partnerským uzlom (predvolené: %u)</translation> + </message> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Neznáma sieť upresnená v -onlynet: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts index 3a65c10604..39dcb6e997 100644 --- a/src/qt/locale/bitcoin_sl_SI.ts +++ b/src/qt/locale/bitcoin_sl_SI.ts @@ -1,7 +1,11 @@ -<TS language="sl_SI" version="2.1"> +<TS language="sl_SI" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Desni klik za urejanje naslovov ali oznak</translation> + </message> + <message> <source>Create a new address</source> <translation>Ustvari nov naslov</translation> </message> @@ -19,7 +23,7 @@ </message> <message> <source>C&lose</source> - <translation>&Zapri (close)</translation> + <translation>&Zapri</translation> </message> <message> <source>&Copy Address</source> @@ -31,7 +35,7 @@ </message> <message> <source>Export the data in the current tab to a file</source> - <translation>Izvozi podatke v trenutni zavih v datoteko</translation> + <translation>Izvozi podatke v trenutnem zavihku v datoteko</translation> </message> <message> <source>&Export</source> @@ -39,15 +43,15 @@ </message> <message> <source>&Delete</source> - <translation>&Zbriši</translation> + <translation>I&zbriši</translation> </message> <message> <source>Choose the address to send coins to</source> - <translation>Izberi naslov prejemnika kovancev</translation> + <translation>Izbira naslova, na katerega pošiljate plačilo</translation> </message> <message> <source>Choose the address to receive coins with</source> - <translation>Izberi naslov pošiljatelja kovancev</translation> + <translation>Izbira naslova za prejem plačila</translation> </message> <message> <source>C&hoose</source> @@ -55,19 +59,19 @@ </message> <message> <source>Sending addresses</source> - <translation>Naslovi za pošiljanje</translation> + <translation>Imenik naslovov za pošiljanje</translation> </message> <message> <source>Receiving addresses</source> - <translation>Naslovi za prejemanje</translation> + <translation>Imenik naslovov za prejemanje</translation> </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>To so tvoji Bitcoin naslovi za pošiljanje plačil. Vedno preveri znesek in prejemnikov naslov pred pošiljanjem kovancev.</translation> + <translation>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.</translation> </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> - <translation>To so tvoji Bitcoin naslovi za prejemanje plačil. Priporočljivo je uporabljati nov prejemni naslov za vsako izmed transakcij.</translation> + <translation>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.</translation> </message> <message> <source>Copy &Label</source> @@ -87,9 +91,13 @@ </message> <message> <source>Exporting Failed</source> - <translation>Neuspešen izvoz</translation> + <translation>Seznama naslovov ni bilo mogoče izvoziti.</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Napaka pri shranjevanju seznama naslovov v datoteko %1. Prosimo, poskusite znova.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -102,14 +110,14 @@ </message> <message> <source>(no label)</source> - <translation>(ni oznake)</translation> + <translation>(brez oznake)</translation> </message> </context> <context> <name>AskPassphraseDialog</name> <message> <source>Passphrase Dialog</source> - <translation>Poziv gesla</translation> + <translation>Vnos gesla</translation> </message> <message> <source>Enter passphrase</source> @@ -148,58 +156,70 @@ <translation>Zamenjaj geslo</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Vnesite staro in novo geslo denarnice.</translation> - </message> - <message> <source>Confirm wallet encryption</source> - <translation>Potrdi šifriranje denarnice</translation> + <translation>Potrditev šifriranja denarnice</translation> </message> <message> <source>Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!</source> - <translation>Opozorilo: V primeru izgube gesla kriptirane denarnice, boš <b>IZGUBIL VSE SVOJE BITCOINE</b>!</translation> + <translation>Opozorilo: V primeru izgube gesla šifrirane denarnice, boste <b>IZGUBILI VSE BITCOINE V DENARNICI</b>!</translation> </message> <message> <source>Are you sure you wish to encrypt your wallet?</source> <translation>Ali ste prepričani, da želite šifrirati vašo denarnico?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>Warning: The Caps Lock key is on!</source> - <translation>Opozorilo: imate prižgan Cap Lock</translation> + <translation>Opozorilo: imate vklopljene velike črke (Caps Lock)</translation> </message> <message> <source>Wallet encrypted</source> - <translation>Denarnica šifrirana</translation> + <translation>Denarnica je šifrirana</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin se bo zaprl, da bi dokončal proces šifriranja. Zapomnite si, da šifriranje vaše denarnice ne more popolnoma zaščititi pred krajami zlonamernih programov, ki bi lahko bili nameščeni na vašem računalniku.</translation> + <source>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>.</source> + <translation>Vnesite novo geslo. Prosimo, da uporabite geslo sestavljeno iz <b>deset ali več</b> naključnih znakov, ali <b>osem ali več</b> besed.</translation> + </message> + <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Vnesite staro in novo geslo denarnice.</translation> </message> <message> <source>Wallet encryption failed</source> - <translation>Šifriranje denarnice spodletelo</translation> + <translation>Denarnice ni bilo mogoče šifrirati.</translation> </message> <message> <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> - <translation>Šifriranje denarnice spodletelo zaradi notranje napake. Vaša denarnica ni šifrirana.</translation> + <translation>Prišlo je do napake. Denarnice ni bilo mogoče šifrirati.</translation> </message> <message> <source>The supplied passphrases do not match.</source> - <translation>Vnešeno geslo se ne ujema</translation> + <translation>Vnešeni gesli se ne ujemata</translation> </message> <message> <source>Wallet unlock failed</source> - <translation>Odklep denarnice spodletel</translation> + <translation>Denarnice ni bilo mogoče odkleniti.</translation> </message> <message> <source>The passphrase entered for the wallet decryption was incorrect.</source> - <translation>Geslo za dešifriranje denarnice, ki ste ga vnesli, ni pravilno.</translation> + <translation>Vnesli ste napačno geslo za dešifriranje denarnice.</translation> </message> <message> <source>Wallet decryption failed</source> - <translation>Dešifriranje denarnice spodletelo</translation> + <translation>Denarnice ni bilo mogoče dešifrirati.</translation> </message> - </context> + <message> + <source>Wallet passphrase was successfully changed.</source> + <translation>Geslo za dostop do denarnice je bilo uspešno zamenjano.</translation> + </message> +</context> <context> <name>BitcoinGUI</name> <message> @@ -208,11 +228,11 @@ </message> <message> <source>Synchronizing with network...</source> - <translation>Sinhroniziranje z omrežjem ...</translation> + <translation>Dohitevam omrežje ...</translation> </message> <message> <source>&Overview</source> - <translation>&Pregled</translation> + <translation>Pre&gled</translation> </message> <message> <source>Node</source> @@ -220,7 +240,7 @@ </message> <message> <source>Show general overview of wallet</source> - <translation>Pokaži splošen pregled denarnice</translation> + <translation>Oglejte si splošne informacije o vaši denarnici</translation> </message> <message> <source>&Transactions</source> @@ -228,7 +248,7 @@ </message> <message> <source>Browse transaction history</source> - <translation>Brskaj po zgodovini transakcij</translation> + <translation>Brskajte po zgodovini transakcij</translation> </message> <message> <source>E&xit</source> @@ -236,7 +256,7 @@ </message> <message> <source>Quit application</source> - <translation>Izhod iz aplikacije</translation> + <translation>Ustavite program</translation> </message> <message> <source>About &Qt</source> @@ -244,7 +264,7 @@ </message> <message> <source>Show information about Qt</source> - <translation>Prikaži informacije o Qt</translation> + <translation>Oglejte si informacije o Qt</translation> </message> <message> <source>&Options...</source> @@ -256,7 +276,7 @@ </message> <message> <source>&Backup Wallet...</source> - <translation>&Napravi varnostno kopijo denarnice ...</translation> + <translation>Shrani &varnostno kopijo denarnice ...</translation> </message> <message> <source>&Change Passphrase...</source> @@ -264,15 +284,15 @@ </message> <message> <source>&Sending addresses...</source> - <translation>&Pošiljanje naslovov...</translation> + <translation>Naslovi za po&šiljanje ...</translation> </message> <message> <source>&Receiving addresses...</source> - <translation>&Prejemanje naslovov...</translation> + <translation>Naslovi za &prejemanje...</translation> </message> <message> <source>Open &URI...</source> - <translation>Odpri &URI...</translation> + <translation>Odpri &URI ...</translation> </message> <message> <source>Bitcoin Core client</source> @@ -280,27 +300,23 @@ </message> <message> <source>Importing blocks from disk...</source> - <translation>Uvažam bloke z diska...</translation> + <translation>Uvažam bloke z diska ...</translation> </message> <message> <source>Reindexing blocks on disk...</source> - <translation>Poustvarjam kazalo blokov na disku...</translation> + <translation>Poustvarjam kazalo blokov na disku ...</translation> </message> <message> <source>Send coins to a Bitcoin address</source> - <translation>Pošlji kovance na Bitcoin naslov</translation> - </message> - <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Spremeni konfiguracijo nastavitev za Bitcoin</translation> + <translation>Izvedite plačilo na naslov Bitcoin</translation> </message> <message> <source>Backup wallet to another location</source> - <translation>Napravi varnostno kopijo denarnice na drugo lokacijo</translation> + <translation>Shranite varnostno kopijo svoje denarnice na drugo lokacijo</translation> </message> <message> <source>Change the passphrase used for wallet encryption</source> - <translation>Spremeni šifrirno geslo denarnice</translation> + <translation>Spremenite geslo za šifriranje denarnice</translation> </message> <message> <source>&Debug window</source> @@ -308,7 +324,11 @@ </message> <message> <source>Open debugging and diagnostic console</source> - <translation>Odpri razhroščevalno in diagnostično konzolo</translation> + <translation>Odprite razhroščevalno in diagnostično konzolo</translation> + </message> + <message> + <source>&Verify message...</source> + <translation>&Preveri sporočilo ...</translation> </message> <message> <source>Bitcoin</source> @@ -324,11 +344,11 @@ </message> <message> <source>&Receive</source> - <translation>&Sprejmi</translation> + <translation>P&rejmi</translation> </message> <message> <source>Show information about Bitcoin Core</source> - <translation>Pokaži informacije o Bitcoin Core</translation> + <translation>Oglejte si informacije o programu</translation> </message> <message> <source>&Show / Hide</source> @@ -340,11 +360,15 @@ </message> <message> <source>Encrypt the private keys that belong to your wallet</source> - <translation>Šifiraj zasebne ključe v moji denarnici</translation> + <translation>Šifrirajte zasebne ključe, ki se nahajajo v denarnici</translation> </message> <message> <source>Sign messages with your Bitcoin addresses to prove you own them</source> - <translation>Za dokaz, da ste lastniki sporočil, se podpišite z Bitcoin naslovom</translation> + <translation>Podpišite poljubno sporočilo z enim svojih naslovov Bitcoin, da prejemniku sporočila dokažete, da je ta naslov v vaši lasti.</translation> + </message> + <message> + <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source> + <translation>Preverite, če je bilo prejeto sporočilo podpisano z določenim naslovom Bitcoin</translation> </message> <message> <source>&File</source> @@ -364,39 +388,63 @@ </message> <message> <source>Bitcoin Core</source> - <translation>Jedro Bitcoina</translation> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>Request payments (generates QR codes and bitcoin: URIs)</source> + <translation>Zahtevajte plačilo (ustvarite zahtevek s kodo QR in URI tipa bitcoin:)</translation> </message> <message> <source>&About Bitcoin Core</source> - <translation>&O jedru Bitcoina</translation> + <translation>&O programu</translation> + </message> + <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Spremenite programske nastavitve</translation> </message> <message> <source>Show the list of used sending addresses and labels</source> - <translation>Prikaži seznam uporabljenih naslovov za pošiljanje in oznak</translation> + <translation>Preglejte in uredite seznam naslovov, na katere ste kdaj poslali plačila</translation> </message> <message> <source>Show the list of used receiving addresses and labels</source> - <translation>Prikaži seznam uporabljenih sprejemnih naslovov in oznak</translation> + <translation>Preglejte in uredite seznam naslovov, na katere ste kdaj prejeli plačila</translation> </message> <message> <source>Open a bitcoin: URI or payment request</source> - <translation>Odpri Bitcoin: URI ali zahteva o plačilu</translation> + <translation>Izvedite plačilo iz zahtevka v datoteki ali iz URI tipa bitcoin:</translation> + </message> + <message> + <source>&Command-line options</source> + <translation>Opcije &ukazne vrstice</translation> + </message> + <message> + <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> + <translation>Oglejte si seznam in kratek opis vseh opcij pri zagonu programa iz ukazne vrstice</translation> </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n aktivna povezava v bitcoin omrežje</numerusform><numerusform>%n aktivni povezavi v bitcoin omrežje</numerusform><numerusform>%n aktivnih povezav v bitcoin omrežje</numerusform><numerusform>%n aktivnih povezav v bitcoin omrežje</numerusform></translation> + <translation><numerusform>%n aktivna povezava v bitcoin omrežje</numerusform><numerusform>%n aktivni povezavi v bitcoin omrežje</numerusform><numerusform>%n aktivne povezave v bitcoin omrežje</numerusform><numerusform>%n aktivnih povezav v bitcoin omrežje</numerusform></translation> + </message> + <message> + <source>No block source available...</source> + <translation>Ni virov za prenos blokov ...</translation> + </message> + <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>%n obdelan blok zgodovine transakcij.</numerusform><numerusform>%n obdelana bloka zgodovine transakcij.</numerusform><numerusform>%n obdelani bloki zgodovine transakcij.</numerusform><numerusform>%n obdelanih blokov zgodovine transakcij.</numerusform></translation> </message> <message numerus="yes"> <source>%n hour(s)</source> - <translation><numerusform>%n ura</numerusform><numerusform>%n uri</numerusform><numerusform>%n ure</numerusform><numerusform>%n ura</numerusform></translation> + <translation><numerusform>%n ura</numerusform><numerusform>%n uri</numerusform><numerusform>%n ure</numerusform><numerusform>%n ur</numerusform></translation> </message> <message numerus="yes"> <source>%n day(s)</source> - <translation><numerusform>%n dan</numerusform><numerusform>%n dneva</numerusform><numerusform>%n dnevi</numerusform><numerusform>%n dni</numerusform></translation> + <translation><numerusform>%n dan</numerusform><numerusform>%n dneva</numerusform><numerusform>%n dni</numerusform><numerusform>%n dni</numerusform></translation> </message> <message numerus="yes"> <source>%n week(s)</source> - <translation><numerusform>%n teden</numerusform><numerusform>%n tedna</numerusform><numerusform>%n tedni</numerusform><numerusform>%n tednov</numerusform></translation> + <translation><numerusform>%n teden</numerusform><numerusform>%n tedna</numerusform><numerusform>%n tedne</numerusform><numerusform>%n tednov</numerusform></translation> </message> <message> <source>%1 and %2</source> @@ -408,11 +456,15 @@ </message> <message> <source>%1 behind</source> - <translation>%1 odzadaj</translation> + <translation>imam še %1 zaostanka</translation> + </message> + <message> + <source>Last received block was generated %1 ago.</source> + <translation>Zadnji prejeti blok je bil ustvarjen %1 nazaj.</translation> </message> <message> <source>Transactions after this will not yet be visible.</source> - <translation>Transkacija za tem ne bo bila še na voljo.</translation> + <translation>Novejše transakcije še ne bodo vidne.</translation> </message> <message> <source>Error</source> @@ -432,29 +484,47 @@ </message> <message> <source>Catching up...</source> - <translation>Pridobivanje ...</translation> + <translation>Dohitevam omrežje ...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Odlivi</translation> + <source>Date: %1 +</source> + <translation>Datum: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Prilivi</translation> + <source>Amount: %1 +</source> + <translation>Znesek: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Datum: %1 -Količina: %2 -Vrsta: %3 -Naslov: %4 + <translation>Vrsta: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Oznaka: %1 </translation> </message> <message> + <source>Address: %1 +</source> + <translation>Naslov: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Odlivi</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Prilivi</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Denarnica je <b>šifrirana</b> in trenutno <b>odklenjena</b></translation> </message> @@ -467,26 +537,30 @@ Naslov: %4 <name>ClientModel</name> <message> <source>Network Alert</source> - <translation>Omrežno Opozorilo</translation> + <translation>Omrežno opozorilo</translation> </message> </context> <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>Izbira vhodnih kovancev</translation> + </message> + <message> <source>Quantity:</source> - <translation>Količina:</translation> + <translation>Št.vhodov:</translation> </message> <message> <source>Bytes:</source> - <translation>Biti:</translation> + <translation>Št.bajtov:</translation> </message> <message> <source>Amount:</source> - <translation>Količina:</translation> + <translation>Znesek:</translation> </message> <message> <source>Priority:</source> - <translation>Prednostno mesto:</translation> + <translation>Prioriteta:</translation> </message> <message> <source>Fee:</source> @@ -497,16 +571,20 @@ Naslov: %4 <translation>Prah:</translation> </message> <message> + <source>After Fee:</source> + <translation>Po proviziji:</translation> + </message> + <message> <source>Change:</source> - <translation>Sprememba:</translation> + <translation>Vračilo:</translation> </message> <message> <source>(un)select all</source> - <translation>(ne)izberi vse</translation> + <translation>izberi vse/nič</translation> </message> <message> <source>Tree mode</source> - <translation>Drevo</translation> + <translation>Drevesni prikaz</translation> </message> <message> <source>List mode</source> @@ -514,7 +592,15 @@ Naslov: %4 </message> <message> <source>Amount</source> - <translation>Količina</translation> + <translation>Znesek</translation> + </message> + <message> + <source>Received with label</source> + <translation>Oznaka priliva</translation> + </message> + <message> + <source>Received with address</source> + <translation>Naslov priliva</translation> </message> <message> <source>Date</source> @@ -522,7 +608,7 @@ Naslov: %4 </message> <message> <source>Confirmations</source> - <translation>Potrdila</translation> + <translation>Potrditve</translation> </message> <message> <source>Confirmed</source> @@ -530,7 +616,7 @@ Naslov: %4 </message> <message> <source>Priority</source> - <translation>Prednostno mesto</translation> + <translation>Prioriteta</translation> </message> <message> <source>Copy address</source> @@ -542,7 +628,7 @@ Naslov: %4 </message> <message> <source>Copy amount</source> - <translation>Kopiraj količino</translation> + <translation>Kopiraj znesek</translation> </message> <message> <source>Copy transaction ID</source> @@ -558,19 +644,23 @@ Naslov: %4 </message> <message> <source>Copy quantity</source> - <translation>Kopiraj količino</translation> + <translation>Kopiraj število vhodov</translation> </message> <message> <source>Copy fee</source> - <translation>Kopiraj provizijo</translation> + <translation>Kopiraj znesek provizije</translation> + </message> + <message> + <source>Copy after fee</source> + <translation>Kopiraj končni znesek</translation> </message> <message> <source>Copy bytes</source> - <translation>Kopiraj bite</translation> + <translation>Kopiraj število bajtov</translation> </message> <message> <source>Copy priority</source> - <translation>Kopiraj prednostno mesto</translation> + <translation>Kopiraj prioriteto</translation> </message> <message> <source>Copy dust</source> @@ -578,7 +668,7 @@ Naslov: %4 </message> <message> <source>Copy change</source> - <translation>Kopiraj drobiž</translation> + <translation>Kopiraj znesek vračila</translation> </message> <message> <source>highest</source> @@ -598,7 +688,7 @@ Naslov: %4 </message> <message> <source>medium</source> - <translation>srednje</translation> + <translation>srednja</translation> </message> <message> <source>low-medium</source> @@ -622,11 +712,23 @@ Naslov: %4 </message> <message> <source>none</source> - <translation>Nič</translation> + <translation>nič</translation> + </message> + <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Oznaka postane rdeča, če je transakcije večja od 1000 bajtov.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Oznaka postane rdeča, če je prioriteta transakcije manjša kot "srednja".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Oznaka postane rdeča, če je znesek manjši od %1.</translation> </message> <message> <source>Can vary +/- %1 satoshi(s) per input.</source> - <translation>Se lahko razlikuje +/- %1 satošijev na vnos.</translation> + <translation>Lahko variira +/- %1 satoshijev na vhod.</translation> </message> <message> <source>yes</source> @@ -637,32 +739,28 @@ Naslov: %4 <translation>ne</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>V primeru, da je velikost transakcije večja od 1000 bitov, se ta oznaka se obarva rdeče.</translation> + <source>This means a fee of at least %1 per kB is required.</source> + <translation>To pomeni, da je zahtevana provizija v višini vsaj %1 na KiB.</translation> </message> <message> <source>Can vary +/- 1 byte per input.</source> - <translation>Se lahko razlikuje +/- 1 byte na vnos.</translation> + <translation>Lahko variira +/-1 bajt na vhod.</translation> </message> <message> <source>Transactions with higher priority are more likely to get included into a block.</source> <translation>Transakcije z višjo prioriteto imajo boljše možnosti za vključitev v blok.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Oznaka se obarva rdeče, kadar je prioriteta manjša od "srednje".</translation> - </message> - <message> <source>(no label)</source> - <translation>(ni oznake)</translation> + <translation>(brez oznake)</translation> </message> <message> <source>change from %1 (%2)</source> - <translation>drobiž od %1 (%2)</translation> + <translation>vračilo od %1 (%2)</translation> </message> <message> <source>(change)</source> - <translation>(drobiž)</translation> + <translation>(vračilo)</translation> </message> </context> <context> @@ -677,11 +775,11 @@ Naslov: %4 </message> <message> <source>The label associated with this address list entry</source> - <translation>Oznaka je povezana s tem vnosom seznama naslovov</translation> + <translation>Oznaka, pod katero je spodnji naslov naveden v vašem imeniku naslovov.</translation> </message> <message> <source>The address associated with this address list entry. This can only be modified for sending addresses.</source> - <translation>Naslov povezan s tem vnosom seznama naslovov. Sprememba je mogoča le za naslove namenjene pošiljanju.</translation> + <translation>Naslov tega vnosa v imeniku. Spremeniti ga je mogoče le pri vnosih iz imenika naslovov za pošiljanje.</translation> </message> <message> <source>&Address</source> @@ -704,23 +802,27 @@ Naslov: %4 <translation>Uredi naslov za odlive</translation> </message> <message> + <source>The entered address "%1" is already in the address book.</source> + <translation>Vnešeni naslov %1 je že v imeniku.</translation> + </message> + <message> <source>The entered address "%1" is not a valid Bitcoin address.</source> - <translation>Vnešeni naslov "%1" ni veljaven Bitcoin naslov.</translation> + <translation>Vnešeni naslov %1 ni veljaven naslov Bitcoin.</translation> </message> <message> <source>Could not unlock wallet.</source> - <translation>Ni bilo moč odkleniti denarnice.</translation> + <translation>Denarnice ni bilo mogoče odkleniti.</translation> </message> <message> <source>New key generation failed.</source> - <translation>Generiranje novega ključa je spodletelo.</translation> + <translation>Novega ključa ni bilo mogoče ustvariti.</translation> </message> </context> <context> <name>FreespaceChecker</name> <message> <source>A new data directory will be created.</source> - <translation>Ustvarjena bo nova mapa za shranjevanje podatkov.</translation> + <translation>Ustvarjena bo nova podatkovna mapa.</translation> </message> <message> <source>name</source> @@ -728,7 +830,7 @@ Naslov: %4 </message> <message> <source>Directory already exists. Add %1 if you intend to create a new directory here.</source> - <translation>Mapa že obstaja. Dodaj %1, če tu želiš ustvariti novo mapo.</translation> + <translation>Mapa že obstaja. Dodajte %1, če tu želite ustvariti novo mapo.</translation> </message> <message> <source>Path already exists, and is not a directory.</source> @@ -736,14 +838,14 @@ Naslov: %4 </message> <message> <source>Cannot create data directory here.</source> - <translation>Na tem mestu ne moreš ustvariti nove mape.</translation> + <translation>Na tem mestu ni mogoče ustvariti nove mape.</translation> </message> </context> <context> <name>HelpMessageDialog</name> <message> <source>Bitcoin Core</source> - <translation>Jedro Bitcoina</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>version</source> @@ -755,7 +857,7 @@ Naslov: %4 </message> <message> <source>About Bitcoin Core</source> - <translation>O jedru Bitcoina</translation> + <translation>O programu Bitcoin Core</translation> </message> <message> <source>Command-line options</source> @@ -769,30 +871,6 @@ Naslov: %4 <source>command-line options</source> <translation>možnosti ukazne vrstice</translation> </message> - <message> - <source>UI options</source> - <translation>možnosti uporabniškega vmesnika</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Nastavi jezik, npr. "sl_SI" (privzeto: jezikovna oznaka sistema)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Zaženi pomanjšano</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Nastavi korenske SSL certifikate za plačilni zahtevek (privzeto: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Ob zagonu prikaži uvodni zaslon (privzeto: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Ob zagonu izberi mapo za shranjevanje podatkov (privzeto: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -802,36 +880,40 @@ Naslov: %4 </message> <message> <source>Welcome to Bitcoin Core.</source> - <translation>Dobrodošli v jedru Bitcoina</translation> + <translation>Dobrodošli v programu Bitcoin Core.</translation> </message> <message> <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source> - <translation>Program poganjaš prvič. Izberi kje bo Bitcoin Core shranjeval svoje podatke.</translation> + <translation>To je prvi zagon programa, zato lahko izberete mapo, v katero bo program shranjeval podatke.</translation> </message> <message> <source>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.</source> - <translation>Bitcoin Core bo prenesel in shranil kopijo Bitcoin verige blokov. V izbrano mapo bo shranjenih vsaj %1 GB podatkov, ta količina pa bo sčasoma še naraščala. Denarnica bo prav tako shranjena v to mapo.</translation> + <translation>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.</translation> </message> <message> <source>Use the default data directory</source> - <translation>Uporabi privzeto mapo za shranjevanje podatkov.</translation> + <translation>Uporabi privzeto podatkovno mapo</translation> </message> <message> <source>Use a custom data directory:</source> - <translation>Uporabi to mapo za shranjevanje podatkov:</translation> + <translation>Uporabi to podatkovno mapo:</translation> </message> <message> <source>Bitcoin Core</source> - <translation>Jedro Bitcoina</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>Error: Specified data directory "%1" cannot be created.</source> - <translation>Napaka: Ne morem ustvariti mape "%1".</translation> + <translation>Napaka: Ni mogoče ustvariti mape "%1".</translation> </message> <message> <source>Error</source> <translation>Napaka</translation> </message> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform></translation> + </message> </context> <context> <name>OpenURIDialog</name> @@ -841,7 +923,7 @@ Naslov: %4 </message> <message> <source>Open payment request from URI or file</source> - <translation>Odpri zahtevo o plačilo od ORI ali datoteke</translation> + <translation>Vnesite zahtevek za plačilo iz URI ali pa ga naložite iz datoteke</translation> </message> <message> <source>URI:</source> @@ -849,11 +931,11 @@ Naslov: %4 </message> <message> <source>Select payment request file</source> - <translation>Izberi datoteko plačilnega zahtevka</translation> + <translation>Izbiranje datoteke z zahtevkom za plačilo</translation> </message> <message> <source>Select payment request file to open</source> - <translation>Izberi datoteko plačilnega zahtevka</translation> + <translation>Izberite datoteko, ki vsebuje zahtevek za plačilo</translation> </message> </context> <context> @@ -867,64 +949,112 @@ Naslov: %4 <translation>&Glavno</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Po prijavi v sistem samodejno zaženite Bitcoin.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Zaženi Bitcoin ob prijavi v sistem</translation> - </message> - <message> <source>Size of &database cache</source> - <translation>Velikost lokalne zbirke &podatkovne baze</translation> + <translation>Velikost &predpomnilnika podatkovne baze</translation> </message> <message> <source>MB</source> - <translation>megabite</translation> + <translation>MiB</translation> + </message> + <message> + <source>Number of script &verification threads</source> + <translation>Število programskih &niti za preverjanje</translation> </message> <message> <source>Accept connections from outside</source> - <translation>Sprejmi povezave od zunaj</translation> + <translation>Sprejemaj zunanje povezave</translation> </message> <message> <source>Allow incoming connections</source> - <translation>Dovoli prihajajoče povezave</translation> + <translation>Dovoli dohodne povezave</translation> </message> <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> - <translation>IP naslov proxy strežnika (npr. IPv4: 127.0.0.1 ali IPv6: ::1)</translation> + <translation>Naslov IP posredniškega strežnika (npr. IPv4: 127.0.0.1 ali IPv6: ::1)</translation> + </message> + <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Nastavitev jezika uporabniškega vmesnika programa. Nova nastavitev jezika bo uporabljena šele, ko boste znova zagnali program.</translation> + </message> + <message> + <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> + <translation>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 |.</translation> + </message> + <message> + <source>Third party transaction URLs</source> + <translation>Zunanje povezave za transakcije</translation> + </message> + <message> + <source>Active command-line options that override above options:</source> + <translation>Aktivne opcije iz ukazne vrstice, ki preglasijo zgornje opcije:</translation> + </message> + <message> + <source>Reset all client options to default.</source> + <translation>Ponastavi vse nastavitve programa na privzete vrednosti.</translation> </message> <message> <source>&Reset Options</source> - <translation>&Opcije resetiranja</translation> + <translation>&Ponastavi nastavitve</translation> </message> <message> <source>&Network</source> <translation>&Omrežje</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Ob uporabnikovi prijavi v sistem se bo program samodejno zagnal</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Zaženi program ob prijavi v sistem</translation> + </message> + <message> + <source>(0 = auto, <0 = leave that many cores free)</source> + <translation>(0 = samodejno, <0 = toliko procesorskih jeder naj ostane prostih)</translation> + </message> + <message> <source>W&allet</source> <translation>&Denarnica</translation> </message> <message> <source>Expert</source> - <translation>Poznavalec</translation> + <translation>Napredne možnosti</translation> </message> <message> <source>Enable coin &control features</source> - <translation>Omogoči Coin & Control funkcijo</translation> + <translation>Omogoči upravljanje s kovanci</translation> + </message> + <message> + <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source> + <translation>Če onemogočite trošenje drobiža iz še nepotrjenih transakcij, potem vrnjenega drobiža ne morete uporabiti, dokler plačilo ni vsaj enkrat potrjeno. Ta opcija vpliva tudi na izračun stanja sredstev.</translation> + </message> + <message> + <source>&Spend unconfirmed change</source> + <translation>Omogoči &trošenje drobiža iz še nepotrjenih plačil</translation> </message> <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> - <translation>Avtomatično odpri vrata Bitcoin odjemalca na usmerjevalniku. To deluje samo, če vaš usmerjevalnik podpira UPnP in je omogočen.</translation> + <translation>Program samodejno odpre ustrezna vrata na usmerjevalniku. To deluje samo, če vaš usmerjevalnik podpira in ima omogočen UPnP.</translation> </message> <message> <source>Map port using &UPnP</source> - <translation>Naslavljanje vrat z uporabo &UPnP</translation> + <translation>Preslikaj vrata z uporabo &UPnP</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Poveži se v omrežje Bitcoin preko posredniškega strežnika SOCKS5.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Poveži se preko posredniškega strežnika SOCKS5 (privzeti strežnik):</translation> </message> <message> <source>Proxy &IP:</source> - <translation>IP posredniškega strežnika:</translation> + <translation>Naslov &IP posredniškega strežnika:</translation> </message> <message> <source>&Port:</source> @@ -932,27 +1062,23 @@ Naslov: %4 </message> <message> <source>Port of the proxy (e.g. 9050)</source> - <translation>Vrata strežnika (npr.: 9050)</translation> + <translation>Vrata posredniškega strežnika (npr. 9050)</translation> </message> <message> <source>&Window</source> - <translation>&Okno</translation> + <translation>O&kno</translation> </message> <message> <source>Show only a tray icon after minimizing the window.</source> - <translation>Prikaži samo pomanjšano ikono programa po pomanjšitvi okna.</translation> + <translation>Po minimiranju okna samo prikaži ikono programa v pladnju.</translation> </message> <message> <source>&Minimize to the tray instead of the taskbar</source> <translation>&Minimiraj na pladenj namesto na opravilno vrstico</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimiziraj namesto izhoda iz programa, ko je okno zaprto. Ko je ta opcija omogočena se bo aplikacija zaprla z izbiro opcije Zapri iz menija. </translation> - </message> - <message> <source>M&inimize on close</source> - <translation>&Minimiziraj na ukaz zapri</translation> + <translation>Ob zapiranju okno zgolj m&inimiraj</translation> </message> <message> <source>&Display</source> @@ -960,15 +1086,19 @@ Naslov: %4 </message> <message> <source>User Interface &language:</source> - <translation>Vmesnik uporabnika &jezik:</translation> + <translation>&Jezik uporabniškega vmesnika:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Tukaj je mogoče nastaviti uporabniški vmesnik za jezike. Ta nastavitev bo prikazana šele, ko boste znova zagnali Bitcoin.</translation> + <source>&Unit to show amounts in:</source> + <translation>&Enota za prikaz zneskov:</translation> </message> <message> - <source>&Unit to show amounts in:</source> - <translation>&</translation> + <source>Choose the default subdivision unit to show in the interface and when sending coins.</source> + <translation>Izberite privzeto mersko enoto za prikaz v uporabniškem vmesniku in pri pošiljanju kovancev.</translation> + </message> + <message> + <source>Whether to show coin control features or not.</source> + <translation>Omogoči dodatno možnost podrobnega nadzora nad posameznimi kovanci v transakcijah.</translation> </message> <message> <source>&OK</source> @@ -976,7 +1106,7 @@ Naslov: %4 </message> <message> <source>&Cancel</source> - <translation>&Prekini</translation> + <translation>&Prekliči</translation> </message> <message> <source>default</source> @@ -984,9 +1114,29 @@ Naslov: %4 </message> <message> <source>none</source> - <translation>Nič</translation> + <translation>nič</translation> </message> - </context> + <message> + <source>Confirm options reset</source> + <translation>Potrditev ponastavitve</translation> + </message> + <message> + <source>Client restart required to activate changes.</source> + <translation>Za uveljavitev sprememb je potreben ponoven zagon programa.</translation> + </message> + <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Program bo zaustavljen. Želite nadaljevati z izhodom?</translation> + </message> + <message> + <source>This change would require a client restart.</source> + <translation>Ta sprememba zahteva ponoven zagon programa.</translation> + </message> + <message> + <source>The supplied proxy address is invalid.</source> + <translation>Vnešeni naslov posredniškega strežnika ni veljaven.</translation> + </message> +</context> <context> <name>OverviewPage</name> <message> @@ -995,23 +1145,39 @@ Naslov: %4 </message> <message> <source>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source> - <translation>Prikazanim podatkom je lahko potekel rok. Vaša denarnica bo po vzpostavitvi povezave samodejno sinhronizirana z Bitcoin omrežjem, ampak ta proces še ni bil zaključen.</translation> + <translation>Prikazani podatki so morda zastareli. Program ob vzpostavitvi povezave samodejno sinhronizira denarnico z omrežjem Bitcoin, a trenutno ta proces še ni zaključen.</translation> </message> <message> <source>Watch-only:</source> - <translation>Samo gledanje</translation> + <translation>Opazovano:</translation> </message> <message> <source>Available:</source> - <translation>Razpoložljivost:</translation> + <translation>Na voljo:</translation> </message> <message> <source>Your current spendable balance</source> - <translation>Vaše trenutno razpoložljivo stanje</translation> + <translation>Skupni znesek vaših sredstev, s katerimi lahko prosto razpolagate</translation> + </message> + <message> + <source>Pending:</source> + <translation>Nepotrjeno:</translation> </message> <message> <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source> - <translation>Skupno število potrjenih transakcij, ki sicer niso bile prištete k razpoložljivem stanju</translation> + <translation>Skupni znesek sredstev s katerimi še ne razpolagate prosto, ker so del še nepotrjenih transakcij.</translation> + </message> + <message> + <source>Immature:</source> + <translation>Nedozorelo:</translation> + </message> + <message> + <source>Mined balance that has not yet matured</source> + <translation>Nedozorel narudarjeni znesek</translation> + </message> + <message> + <source>Balances</source> + <translation>Stanje sredstev</translation> </message> <message> <source>Total:</source> @@ -1019,11 +1185,31 @@ Naslov: %4 </message> <message> <source>Your current total balance</source> - <translation>Vaše trenutno skupno stanje</translation> + <translation>Trenutna vsota vseh vaših sredstev</translation> </message> <message> - <source>out of sync</source> - <translation>iz sinhronizacije</translation> + <source>Your current balance in watch-only addresses</source> + <translation>Trenutno stanje vaših sredstev na opazovanih naslovih</translation> + </message> + <message> + <source>Spendable:</source> + <translation>Na voljo:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Nedavne transakcije</translation> + </message> + <message> + <source>Unconfirmed transactions to watch-only addresses</source> + <translation>Nepotrjene transakcije na opazovanih naslovih</translation> + </message> + <message> + <source>Mined balance in watch-only addresses that has not yet matured</source> + <translation>Nedozoreli narudarjeni znesek na opazovanih naslovih</translation> + </message> + <message> + <source>Current total balance in watch-only addresses</source> + <translation>Trenutno skupno stanje sredstev na opazovanih naslovih</translation> </message> </context> <context> @@ -1037,16 +1223,80 @@ Naslov: %4 <translation>Neveljaven naslov plačila %1</translation> </message> <message> + <source>Payment request rejected</source> + <translation>Zahtevek za plačilo je bil zavrnjen.</translation> + </message> + <message> + <source>Payment request network doesn't match client network.</source> + <translation>Zahtevek za plačilo in vaš odjemalec se nahajata na dveh različnih omrežjih.</translation> + </message> + <message> + <source>Payment request is not initialized.</source> + <translation>Zahtevek za plačilo ni inicializiran.</translation> + </message> + <message> + <source>Requested payment amount of %1 is too small (considered dust).</source> + <translation>Znesek %1 v zahtevku za plačilo je prenizek (smatran za prah.)</translation> + </message> + <message> <source>Payment request error</source> - <translation>Napaka pri zahtevi plačila</translation> + <translation>Napaka pri zahtevku za plačilo</translation> + </message> + <message> + <source>Cannot start bitcoin: click-to-pay handler</source> + <translation>Ni mogoče zagnati rokovalca plačilnih povezav tipa bitcoin:.</translation> + </message> + <message> + <source>Payment request fetch URL is invalid: %1</source> + <translation>Naslov URL za pridobitev zahtevka za plačilo ni veljaven: %1</translation> + </message> + <message> + <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source> + <translation>URI je neprepoznaven! Možno je, da je naslov Bitcoin neveljaven, ali da so parametri v URI napačno oblikovani.</translation> + </message> + <message> + <source>Payment request file handling</source> + <translation>Rokovanje z datoteko z zahtevkom za plačilo</translation> + </message> + <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>Datoteke z zahtevkom za plačilo ni mogoče prebrati! Možno je, da datoteka ni veljavna.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Zahtevek za plačilo je potekel.</translation> + </message> + <message> + <source>Unverified payment requests to custom payment scripts are unsupported.</source> + <translation>Nepreverjeni zahtevki za plačilo, namenjeni plačilni skripti po meri, niso podprti.</translation> + </message> + <message> + <source>Invalid payment request.</source> + <translation>Neveljaven zahtevek za plačilo.</translation> + </message> + <message> + <source>Refund from %1</source> + <translation>Povračilo od %1</translation> + </message> + <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>Zahtevek za plačilo %1 je prevelik (%2 bajtov, dovoljenih je %3 bajtov.)</translation> + </message> + <message> + <source>Payment request DoS protection</source> + <translation>Zaščita pred napadom denial-of-service zahtevka za plačilo</translation> </message> <message> <source>Error communicating with %1: %2</source> <translation>Napaka pri povezavi z %1: %2</translation> </message> <message> + <source>Payment request cannot be parsed!</source> + <translation>Zahtevek za plačilo je neprepoznaven!</translation> + </message> + <message> <source>Bad response from server %1</source> - <translation>Slab odziv strežnika %1</translation> + <translation>Napačen odziv strežnika %1</translation> </message> <message> <source>Payment acknowledged</source> @@ -1060,6 +1310,14 @@ Naslov: %4 <context> <name>PeerTableModel</name> <message> + <source>User Agent</source> + <translation>Ime agenta</translation> + </message> + <message> + <source>Node/Service</source> + <translation>Vozlišče/Storitev</translation> + </message> + <message> <source>Ping Time</source> <translation>Odzivni čas</translation> </message> @@ -1068,26 +1326,46 @@ Naslov: %4 <name>QObject</name> <message> <source>Amount</source> - <translation>Količina</translation> + <translation>Znesek</translation> + </message> + <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>Vnesite naslov Bitcoin (npr. %1):</translation> + </message> + <message> + <source>%1 d</source> + <translation>%1 d</translation> </message> <message> <source>%1 h</source> - <translation>%1 ur</translation> + <translation>%1 h</translation> </message> <message> <source>%1 m</source> - <translation>%1 minut</translation> + <translation>%1 m</translation> + </message> + <message> + <source>%1 s</source> + <translation>%1 s</translation> + </message> + <message> + <source>None</source> + <translation>Nič</translation> </message> <message> <source>N/A</source> <translation>Neznano</translation> </message> - </context> + <message> + <source>%1 ms</source> + <translation>%1 ms</translation> + </message> +</context> <context> <name>QRImageWidget</name> <message> <source>&Save Image...</source> - <translation>&Shrani sliko...</translation> + <translation>&Shrani sliko ...</translation> </message> <message> <source>&Copy Image</source> @@ -1095,7 +1373,7 @@ Naslov: %4 </message> <message> <source>Save QR Code</source> - <translation>Shrani QR kodo</translation> + <translation>Shrani kodo QR</translation> </message> <message> <source>PNG Image (*.png)</source> @@ -1121,6 +1399,14 @@ Naslov: %4 <translation>&Informacije</translation> </message> <message> + <source>Debug window</source> + <translation>Razhroščevalno okno</translation> + </message> + <message> + <source>General</source> + <translation>Splošno</translation> + </message> + <message> <source>Using OpenSSL version</source> <translation>OpenSSL različica v rabi</translation> </message> @@ -1137,6 +1423,10 @@ Naslov: %4 <translation>Omrežje</translation> </message> <message> + <source>Name</source> + <translation>Ime</translation> + </message> + <message> <source>Number of connections</source> <translation>Število povezav</translation> </message> @@ -1149,26 +1439,82 @@ Naslov: %4 <translation>Trenutno število blokov</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Odpre razhroščevalni dnevnik debug.log, ki se nahaja v trenutni podatkovni mapi. Če je datoteka velika, lahko postopek traja nekaj sekund.</translation> + </message> + <message> <source>Received</source> <translation>Prejeto</translation> </message> <message> <source>Sent</source> - <translation>Poslano</translation> + <translation>Oddano</translation> + </message> + <message> + <source>&Peers</source> + <translation>&Soležniki</translation> + </message> + <message> + <source>Select a peer to view detailed information.</source> + <translation>Izberite soležnika, o katerem si želite ogledati podrobnejše informacije.</translation> + </message> + <message> + <source>Direction</source> + <translation>Smer povezave</translation> </message> <message> <source>Version</source> <translation>Različica</translation> </message> <message> + <source>User Agent</source> + <translation>Ime agenta</translation> + </message> + <message> <source>Services</source> <translation>Storitve</translation> </message> <message> + <source>Starting Height</source> + <translation>Začetna višina</translation> + </message> + <message> + <source>Sync Height</source> + <translation>Trenutna višina</translation> + </message> + <message> + <source>Ban Score</source> + <translation>Kazenske točke</translation> + </message> + <message> + <source>Connection Time</source> + <translation>Trajanje povezave</translation> + </message> + <message> + <source>Last Send</source> + <translation>Nazadje oddano</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Nazadnje prejeto</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Oddanih bajtov</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Prejetih bajtov</translation> + </message> + <message> <source>Ping Time</source> <translation>Odzivni čas</translation> </message> <message> + <source>Time Offset</source> + <translation>Časovni odklon</translation> + </message> + <message> <source>Last block time</source> <translation>Čas zadnjega bloka</translation> </message> @@ -1186,11 +1532,19 @@ Naslov: %4 </message> <message> <source>&Clear</source> - <translation>&Pošisti</translation> + <translation>&Počisti</translation> </message> <message> <source>Totals</source> - <translation>Vsote</translation> + <translation>Promet</translation> + </message> + <message> + <source>In:</source> + <translation>Dohodnih:</translation> + </message> + <message> + <source>Out:</source> + <translation>Odhodnih:</translation> </message> <message> <source>Build date</source> @@ -1198,58 +1552,70 @@ Naslov: %4 </message> <message> <source>Debug log file</source> - <translation>Razhroščevalna dnevniška datoteka</translation> + <translation>Razhroščevalni dnevnik</translation> </message> <message> <source>Clear console</source> <translation>Počisti konzolo</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Dobrodošli na Bitcoin RPC konzoli.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Dobrodošli v konzoli RPC programa Bitcoin Core.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> - <translation>Uporabi puščice za gor in dol za navigacijo po zgodovini in <b>Ctrl-L</b> za izbris izpisa na ekranu.</translation> + <translation>Uporabite tipki gor in dol za navigacijo po zgodovini ukazov. Uporabite <b>Ctrl-L</b> za izbris zaslona in zgodovine ukazov.</translation> </message> <message> <source>Type <b>help</b> for an overview of available commands.</source> - <translation>Vtipkaj <b>pomoč</b> za vpogled v razpožljive ukaze.</translation> + <translation>Vtipkajte <b>help</b> za pregled razpoložljivih ukazov.</translation> </message> <message> <source>%1 B</source> - <translation>%1 bitov</translation> + <translation>%1 B</translation> </message> <message> <source>%1 KB</source> - <translation>%1 kilobitov</translation> + <translation>%1 KiB</translation> </message> <message> <source>%1 MB</source> - <translation>%1 megabitov</translation> + <translation>%1 MiB</translation> </message> <message> <source>%1 GB</source> - <translation>%1 gigabitov</translation> + <translation>%1 GiB</translation> + </message> + <message> + <source>via %1</source> + <translation>preko %1</translation> </message> <message> <source>never</source> <translation>nikoli</translation> </message> <message> + <source>Inbound</source> + <translation>Dohodna</translation> + </message> + <message> + <source>Outbound</source> + <translation>Odhodna</translation> + </message> + <message> <source>Unknown</source> <translation>Neznano</translation> </message> <message> <source>Fetching...</source> - <translation>Pridobivam...</translation> + <translation>Pridobivam ...</translation> </message> </context> <context> <name>ReceiveCoinsDialog</name> <message> <source>&Amount:</source> - <translation>&Količina:</translation> + <translation>&Znesek:</translation> </message> <message> <source>&Label:</source> @@ -1260,18 +1626,50 @@ Naslov: %4 <translation>&Sporočilo:</translation> </message> <message> + <source>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.</source> + <translation>Ponovno uporabite enega od že uporabljenih naslovov za prejemanje. Večkratna uporaba istih naslovov za prejemanje negativno vpliva na varnost in zasebnost. To opcijo uporabite samo v primeru, da poustvarjate obstoječ zahtevek za plačilo.</translation> + </message> + <message> + <source>R&euse an existing receiving address (not recommended)</source> + <translation>P&onovno uporabite obstoječ naslov za prejemanje. (Ni priporočeno.)</translation> + </message> + <message> + <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source> + <translation>Neobvezno sporočilo kot priponka zahtevku za plačilo, ki bo prikazano, ko bo zahtevek odprt. Opomba: Opravljeno plačilo.prek omrežja Bitcoin tega sporočila ne bo vsebovalo.</translation> + </message> + <message> <source>An optional label to associate with the new receiving address.</source> - <translation>Pomožna oznaka je povezana z novim sprejemnim naslovom.</translation> + <translation>Oznaka novega sprejemnega naslova.</translation> + </message> + <message> + <source>Use this form to request payments. All fields are <b>optional</b>.</source> + <translation>S tem obrazcem ustvarite nov zahtevek za plačilo. Vsa polja so <b>neobvezna</b>.</translation> + </message> + <message> + <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source> + <translation>Zahtevani znesek. Če ne zahtevate določenega zneska, pustite prazno ali nastavite vrednost na 0.</translation> + </message> + <message> + <source>Clear all fields of the form.</source> + <translation>Počisti vsa polja.</translation> </message> <message> <source>Clear</source> <translation>Počisti</translation> </message> <message> + <source>Requested payments history</source> + <translation>Zgodovina zahtevkov za plačilo</translation> + </message> + <message> <source>&Request payment</source> <translation>&Zahtevaj plačilo</translation> </message> <message> + <source>Show the selected request (does the same as double clicking an entry)</source> + <translation>Prikaz izbranega zahtevka. (Isto funkcijo opravi dvojni klik na zapis.)</translation> + </message> + <message> <source>Show</source> <translation>Pokaži</translation> </message> @@ -1293,7 +1691,7 @@ Naslov: %4 </message> <message> <source>Copy amount</source> - <translation>Kopiraj količino</translation> + <translation>Kopiraj znesek</translation> </message> </context> <context> @@ -1304,19 +1702,23 @@ Naslov: %4 </message> <message> <source>Copy &URI</source> - <translation>Kopraj &URl</translation> + <translation>Kopiraj &URl</translation> </message> <message> <source>Copy &Address</source> - <translation>Kopiraj &Naslov</translation> + <translation>Kopiraj &naslov</translation> </message> <message> <source>&Save Image...</source> - <translation>&Shrani sliko..</translation> + <translation>&Shrani sliko ...</translation> + </message> + <message> + <source>Request payment to %1</source> + <translation>Zahtevek za plačilo z oznako: %1</translation> </message> <message> <source>Payment information</source> - <translation>Informacija o plačilu</translation> + <translation>Informacije o plačilu</translation> </message> <message> <source>URI</source> @@ -1328,7 +1730,7 @@ Naslov: %4 </message> <message> <source>Amount</source> - <translation>Količina</translation> + <translation>Znesek</translation> </message> <message> <source>Label</source> @@ -1340,11 +1742,11 @@ Naslov: %4 </message> <message> <source>Resulting URI too long, try to reduce the text for label / message.</source> - <translation>URI predolg, skušajte zmanjšati besedilo oznake/sporočila.</translation> + <translation>Nastali URI je predolg. Skušajte skrajšati besedilo v oznaki/sporočilu.</translation> </message> <message> <source>Error encoding URI into QR Code.</source> - <translation>Napaka pri kodiranju URIja v QR kodo.</translation> + <translation>Napaka pri pretvorbi URI v kodo QR.</translation> </message> </context> <context> @@ -1363,34 +1765,38 @@ Naslov: %4 </message> <message> <source>Amount</source> - <translation>Količina</translation> + <translation>Znesek</translation> </message> <message> <source>(no label)</source> - <translation>(ni oznake)</translation> + <translation>(brez oznake)</translation> </message> <message> <source>(no message)</source> - <translation>(ni sporočila)</translation> + <translation>(brez sporočila)</translation> </message> <message> <source>(no amount)</source> - <translation>(brez količine)</translation> + <translation>(brez zneska)</translation> </message> </context> <context> <name>SendCoinsDialog</name> <message> <source>Send Coins</source> - <translation>Pošlji kovance</translation> + <translation>Pošlji</translation> + </message> + <message> + <source>Coin Control Features</source> + <translation>Upravljanje s kovanci</translation> </message> <message> <source>Inputs...</source> - <translation>Vnosi...</translation> + <translation>Vhodi ...</translation> </message> <message> <source>automatically selected</source> - <translation>samodejno izbran</translation> + <translation>samodejno izbrani</translation> </message> <message> <source>Insufficient funds!</source> @@ -1398,11 +1804,11 @@ Naslov: %4 </message> <message> <source>Quantity:</source> - <translation>Količina:</translation> + <translation>Št.vhodov:</translation> </message> <message> <source>Bytes:</source> - <translation>Biti:</translation> + <translation>Št.bajtov:</translation> </message> <message> <source>Amount:</source> @@ -1410,15 +1816,95 @@ Naslov: %4 </message> <message> <source>Priority:</source> - <translation>Prednostno mesto:</translation> + <translation>Prioriteta:</translation> </message> <message> <source>Fee:</source> <translation>Provizija:</translation> </message> <message> + <source>After Fee:</source> + <translation>Po proviziji:</translation> + </message> + <message> <source>Change:</source> - <translation>Sprememba:</translation> + <translation>Vračilo:</translation> + </message> + <message> + <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source> + <translation>Če to vključite, nato pa vnesete neveljaven naslov, ali pa pustite polje prazno, bo vrnjen drobiž poslan na novo ustvarjen naslov.</translation> + </message> + <message> + <source>Custom change address</source> + <translation>Naslov za vračilo drobiža po meri</translation> + </message> + <message> + <source>Transaction Fee:</source> + <translation>Provizija:</translation> + </message> + <message> + <source>Choose...</source> + <translation>Izberi ...</translation> + </message> + <message> + <source>collapse fee-settings</source> + <translation>Skrije nastavitve provizije</translation> + </message> + <message> + <source>per kilobyte</source> + <translation>na KiB</translation> + </message> + <message> + <source>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.</source> + <translation>Če je nastavitev zneska provizije po meri enaka 1000 satoshijev, transakcija pa je velika samo 250 bajtov, je obračunani znesek provizije pri nastavitvi "za KiB" samo 250 satoshijev, medtem ko je pri nastavitvi "skupno vsaj" ta znesek 1000 satoshijev. Za transakcije, večje od 1 KiB, se končni znesek pri obeh nastavitvah obračuna na KiB.</translation> + </message> + <message> + <source>Hide</source> + <translation>Skrij</translation> + </message> + <message> + <source>total at least</source> + <translation>skupno vsaj</translation> + </message> + <message> + <source>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.</source> + <translation>Dokler bo v blokih še dovolj prostora za vse nastajajoče transakcije, zadostuje, če plačate samo minimalno provizijo. Ko pa se bo količina vseh transakcij povečala do meja zmogljivosti omrežja, se lahko zgodi, da vaša transakcija brez večje provizije nikoli ne bo potrjena.</translation> + </message> + <message> + <source>(read the tooltip)</source> + <translation>(oglejte si namig)</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Priporočena:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Po meri:</translation> + </message> + <message> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> + <translation>(Samodejni obračun provizije še ni pripravljen. Po navadi izračun traja nekaj blokov ...)</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Čas do potrditve:</translation> + </message> + <message> + <source>normal</source> + <translation>navadno</translation> + </message> + <message> + <source>fast</source> + <translation>hitro</translation> + </message> + <message> + <source>Send as zero-fee transaction if possible</source> + <translation>Pošlji brez provizije, če je mogoče</translation> + </message> + <message> + <source>(confirmation may take longer)</source> + <translation>(čas do potrditve je lahko daljši)</translation> </message> <message> <source>Send to multiple recipients at once</source> @@ -1429,52 +1915,68 @@ Naslov: %4 <translation>Dodaj &prejemnika</translation> </message> <message> + <source>Clear all fields of the form.</source> + <translation>Počisti vsa polja.</translation> + </message> + <message> <source>Dust:</source> <translation>Prah:</translation> </message> <message> <source>Clear &All</source> - <translation>Počisti &vse</translation> + <translation>Počisti &vse </translation> </message> <message> <source>Balance:</source> - <translation>Dobroimetje:</translation> + <translation>Stanje:</translation> </message> <message> <source>Confirm the send action</source> - <translation>Potrdi odlivno dejanje</translation> + <translation>Potrdi pošiljanje</translation> </message> <message> <source>S&end</source> - <translation>P&ošlji</translation> + <translation>&Pošlji</translation> </message> <message> <source>Confirm send coins</source> - <translation>Potrdi odliv kovancev </translation> + <translation>Potrdi pošiljanje</translation> + </message> + <message> + <source>%1 to %2</source> + <translation>%1 na %2</translation> </message> <message> <source>Copy quantity</source> - <translation>Kopiraj količino</translation> + <translation>Kopiraj število vhodov</translation> </message> <message> <source>Copy amount</source> - <translation>Kopiraj količino</translation> + <translation>Kopiraj znesek</translation> </message> <message> <source>Copy fee</source> <translation>Kopiraj provizijo</translation> </message> <message> + <source>Copy after fee</source> + <translation>Kopiraj Po proviziji</translation> + </message> + <message> <source>Copy bytes</source> - <translation>Kopiraj bite</translation> + <translation>Kopiraj bajte</translation> </message> <message> <source>Copy priority</source> - <translation>Kopiraj prednostno mesto</translation> + <translation>Kopiraj prioriteto</translation> </message> <message> <source>Copy change</source> - <translation>Kopiraj drobiž</translation> + <translation>Kopiraj vračilo</translation> + </message> + <message> + <source>Total Amount %1 (= %2)</source> + <translation>Skupni znesek %1 (= %2)</translation> </message> <message> <source>or</source> @@ -1482,23 +1984,59 @@ Naslov: %4 </message> <message> <source>The amount to pay must be larger than 0.</source> - <translation>Količina za plačilo mora biti večja od 0.</translation> + <translation>Znesek za plačilo mora biti večji od 0.</translation> </message> <message> <source>The amount exceeds your balance.</source> - <translation>Količina presega vaše dobroimetje</translation> + <translation>Znesek je večji od stanja sredstev, s katerimi razpolagate.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Najdena kopija naslova, možnost pošiljanja na vsakega izmed naslov le enkrat ob pošiljanju.</translation> + <source>The total exceeds your balance when the %1 transaction fee is included.</source> + <translation>Celotni znesek z vključeno provizijo %1 je večji od stanja sredstev, s katerimi razpolagate.</translation> + </message> + <message> + <source>Transaction creation failed!</source> + <translation>Transakcije ni bilo mogoče ustvariti!</translation> + </message> + <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Provizija, višja od %1, velja za nesmiselno visoko.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Zahtevek za plačilo je potekel.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Predviden začetek potrditev po %n najdenem bloku.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform></translation> + </message> + <message> + <source>Pay only the minimum fee of %1</source> + <translation>Plačilo samo minimalne provizije v znesku %1</translation> + </message> + <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Naslov prejemnika je neveljaven. Prosimo, preverite.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Naslov je že bil uporabljen. Vsak naslov naj bi se uporabil samo enkrat.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> - <translation>Opozorilo: Neveljaven Bitcoin naslov</translation> + <translation>Opozorilo: Neveljaven bitcoin naslov</translation> </message> <message> <source>(no label)</source> - <translation>(ni oznake)</translation> + <translation>(brez oznake)</translation> + </message> + <message> + <source>Warning: Unknown change address</source> + <translation>Opozorilo: Neznan naslov za vračilo drobiža</translation> </message> <message> <source>Copy dust</source> @@ -1506,7 +2044,7 @@ Naslov: %4 </message> <message> <source>Are you sure you want to send?</source> - <translation>Ali ste prepričani, da želite poslati?</translation> + <translation>Ali ste prepričani, da želite izvesti plačilo?</translation> </message> <message> <source>added as transaction fee</source> @@ -1517,7 +2055,7 @@ Naslov: %4 <name>SendCoinsEntry</name> <message> <source>A&mount:</source> - <translation>K&oličina:</translation> + <translation>&Znesek:</translation> </message> <message> <source>Pay &To:</source> @@ -1525,7 +2063,7 @@ Naslov: %4 </message> <message> <source>Enter a label for this address to add it to your address book</source> - <translation>Vnesite oznako za ta naslov, ki bo shranjena v imenik</translation> + <translation>Vnesite oznako, pod katero bo zgornji naslov shranjen v imenik</translation> </message> <message> <source>&Label:</source> @@ -1533,7 +2071,15 @@ Naslov: %4 </message> <message> <source>Choose previously used address</source> - <translation>Izberi zadnje uporabljen naslov</translation> + <translation>Izberite enega od že uporabljenih naslovov</translation> + </message> + <message> + <source>This is a normal payment.</source> + <translation>Plačilo je navadne vrste.</translation> + </message> + <message> + <source>The Bitcoin address to send the payment to</source> + <translation>Naslov Bitcoin, na katerega bo plačilo poslano</translation> </message> <message> <source>Alt+A</source> @@ -1541,41 +2087,85 @@ Naslov: %4 </message> <message> <source>Paste address from clipboard</source> - <translation>Prilepi naslov iz odložišča</translation> + <translation>Prilepite naslov iz odložišča</translation> </message> <message> <source>Alt+P</source> <translation>Alt+P</translation> </message> <message> + <source>Remove this entry</source> + <translation>Izpraznite vsebino polja</translation> + </message> + <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>Znesek plačila bo zmanjšan za znesek provizije. Prejemnik bo prejel manjše število kovancev, kot je bil vnešeni znesek. Če je prejemnikov več, bo provizija med njih enakomerno porazdeljena.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>O&dštej provizijo od zneska</translation> + </message> + <message> <source>Message:</source> <translation>Sporočilo:</translation> </message> <message> + <source>This is an unauthenticated payment request.</source> + <translation>Zahtevek za plačilo je neoverjen.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Zahtevek za plačilo je overjen.</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> - <translation>Vnesite oznako za ta naslov, ki bo shranjena v seznam uporabljenih naslovov</translation> + <translation>Če vnesete oznako za zgornji naslov, se bo skupaj z naslovom shranila v imenk že uporabljenih naslovov</translation> </message> - </context> + <message> + <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source> + <translation>Sporočilo, ki ste ga pripeli na URI tipa bitcoin:. Shranjeno bo skupaj s podatki o transakciji. Opomba: Sporočilo ne bo poslano preko omrežja Bitcoin.</translation> + </message> + <message> + <source>Pay To:</source> + <translation>Prejemnik:</translation> + </message> + <message> + <source>Memo:</source> + <translation>Opomba:</translation> + </message> +</context> <context> <name>ShutdownWindow</name> <message> + <source>Bitcoin Core is shutting down...</source> + <translation>Program se ustavlja ...</translation> + </message> + <message> <source>Do not shut down the computer until this window disappears.</source> - <translation>Ne zaustavite računalnika dokler to okno ne izgine.</translation> + <translation>Dokler to okno ne izgine, ne zaustavljajte računalnika.</translation> </message> </context> <context> <name>SignVerifyMessageDialog</name> <message> <source>Signatures - Sign / Verify a Message</source> - <translation>Podpisi - Podpiši/preveri sporočilo</translation> + <translation>Podpiši / preveri sporočilo</translation> </message> <message> <source>&Sign Message</source> <translation>&Podpiši sporočilo</translation> </message> <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>S svojimi naslovi lahko podpisujete sporočila ali pogodbe in s tem dokazujete, da na teh naslovih lahko prejemate kovance. Bodite previdni in ne podpisujte ničesar nejasnega ali naključnega, ker vas zlikovci preko ribarjenja (phishing) lahko prelisičijo, da na njih prepišete svojo identiteto. Podpisujte samo podrobno opisane izjave, s katerimi se strinjate.</translation> + </message> + <message> + <source>The Bitcoin address to sign the message with</source> + <translation>Naslov Bitcoin, s katerim podpisujete sporočilo</translation> + </message> + <message> <source>Choose previously used address</source> - <translation>Izberi zadnje uporabljen naslov</translation> + <translation>Izberite enega od že uporabljenih naslovov</translation> </message> <message> <source>Alt+A</source> @@ -1583,21 +2173,37 @@ Naslov: %4 </message> <message> <source>Paste address from clipboard</source> - <translation>Prilepi naslov iz odložišča</translation> + <translation>Prilepite naslov iz odložišča</translation> </message> <message> <source>Alt+P</source> <translation>Alt+P</translation> </message> <message> + <source>Enter the message you want to sign here</source> + <translation>Vnesite sporočilo, ki ga želite podpisati</translation> + </message> + <message> <source>Signature</source> <translation>Podpis</translation> </message> <message> + <source>Copy the current signature to the system clipboard</source> + <translation>Kopiranje trenutnega podpisa na sistemsko odložišče.</translation> + </message> + <message> + <source>Sign the message to prove you own this Bitcoin address</source> + <translation>Podpišite sporočilo, da dokažete lastništvo nad zgornjim naslovom.</translation> + </message> + <message> <source>Sign &Message</source> <translation>Podpiši &sporočilo</translation> </message> <message> + <source>Reset all sign message fields</source> + <translation>Počisti vsa polja za vnos v oknu za podpisovanje</translation> + </message> + <message> <source>Clear &All</source> <translation>Počisti &vse </translation> </message> @@ -1606,12 +2212,28 @@ Naslov: %4 <translation>&Preveri sporočilo</translation> </message> <message> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Da preverite verodostojnost sporočila, spodaj vnesite: prejemnikov naslov, prejeto sporočilo (pazljivo skopirajte vse prelome vrstic, presledke, tabulatorje ipd.,) in prejeti podpis. Da se izognete napadom tipa man-in-the-middle, vedite, da iz veljavnega podpisa ne sledi nič drugega, kot tisto, kar je navedeno v sporočilu. Podpis samo potrjuje dejstvo, da ima podpisnik v lasti prejemni naslov, ne more pa dokazati vira nobene transakcije!</translation> + </message> + <message> + <source>The Bitcoin address the message was signed with</source> + <translation>Naslov Bitcoin, s katerim je bilo sporočilo podpisano</translation> + </message> + <message> + <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> + <translation>Preverite, ali je bilo sporočilo v resnici podpisano z navedenim naslovom Bitcoin.</translation> + </message> + <message> <source>Verify &Message</source> - <translation>Preveri &Sporočilo</translation> + <translation>Preveri &sporočilo</translation> + </message> + <message> + <source>Reset all verify message fields</source> + <translation>Počisti vsa polja za vnos v oknu za preverjanje</translation> </message> <message> <source>Click "Sign Message" to generate signature</source> - <translation>Kliknite "Podpiši sporočilo" za ustvaritev podpisa</translation> + <translation>Kliknite "Podpiši sporočilo" da ustvarite podpis</translation> </message> <message> <source>The entered address is invalid.</source> @@ -1619,46 +2241,58 @@ Naslov: %4 </message> <message> <source>Please check the address and try again.</source> - <translation>Prosimo preverite naslov in poizkusite znova.</translation> + <translation>Prosimo preverite naslov in poskusite znova.</translation> + </message> + <message> + <source>The entered address does not refer to a key.</source> + <translation>Vnešeni naslov se ne nanaša na noben ključ.</translation> </message> <message> <source>Wallet unlock was cancelled.</source> - <translation>Odklepanje denarnice je bilo prekinjeno.</translation> + <translation>Odklepanje denarnice je bilo preklicano.</translation> </message> <message> <source>Private key for the entered address is not available.</source> - <translation>Zasebni ključ vnešenega naslov ni na voljo.</translation> + <translation>Zasebni ključ vnešenega naslova ni na voljo.</translation> </message> <message> <source>Message signing failed.</source> - <translation>Podpisovanje sporočila spodletelo.</translation> + <translation>Podpisa ni bilo mogoče ustvariti.</translation> </message> <message> <source>Message signed.</source> - <translation>Sporočilo podpisano.</translation> + <translation>Podpis je bil ustvarjen.</translation> </message> <message> <source>The signature could not be decoded.</source> - <translation>Ni bilo mogoče dešifrirati podpisa.</translation> + <translation>Podpisa ni bilo mogoče razbrati.</translation> </message> <message> <source>Please check the signature and try again.</source> - <translation>Prosimo preverite podpis in poizkusite znova.</translation> + <translation>Prosimo preverite podpis in poskusite znova.</translation> + </message> + <message> + <source>The signature did not match the message digest.</source> + <translation>Podpis se ne ujema z rezultatom funkcije preverjanja.</translation> </message> <message> <source>Message verification failed.</source> - <translation>Pregledovanje sporočila spodletelo.</translation> + <translation>Podpis ni veljaven za to sporočilo.</translation> </message> <message> <source>Message verified.</source> - <translation>Sporočilo pregledano.</translation> + <translation>Podpis sporočila je veljaven.</translation> </message> </context> <context> <name>SplashScreen</name> <message> <source>Bitcoin Core</source> - <translation>Jedro Bitcoina</translation> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>The Bitcoin Core developers</source> + <translation>Bitcoin Core razvijalci</translation> </message> <message> <source>[testnet]</source> @@ -1667,12 +2301,24 @@ Naslov: %4 </context> <context> <name>TrafficGraphWidget</name> - </context> + <message> + <source>KB/s</source> + <translation>KiB/s</translation> + </message> +</context> <context> <name>TransactionDesc</name> <message> <source>Open until %1</source> - <translation>Odpri enoto %1</translation> + <translation>Odprto do %1</translation> + </message> + <message> + <source>conflicted</source> + <translation>v konfliktu</translation> + </message> + <message> + <source>%1/offline</source> + <translation>%1/brez povezave</translation> </message> <message> <source>%1/unconfirmed</source> @@ -1684,7 +2330,11 @@ Naslov: %4 </message> <message> <source>Status</source> - <translation>Stanje</translation> + <translation>Status</translation> + </message> + <message numerus="yes"> + <source>, broadcast through %n node(s)</source> + <translation><numerusform>, posredovano %n vozlišču</numerusform><numerusform>, posredovano %n vozliščema</numerusform><numerusform>, posredovano %n vozliščem</numerusform><numerusform>, posredovano %n vozliščem</numerusform></translation> </message> <message> <source>Date</source> @@ -1711,16 +2361,36 @@ Naslov: %4 <translation>lasten naslov</translation> </message> <message> + <source>watch-only</source> + <translation>opazovano</translation> + </message> + <message> <source>label</source> <translation>oznaka</translation> </message> <message> + <source>Credit</source> + <translation>V dobro</translation> + </message> + <message numerus="yes"> + <source>matures in %n more block(s)</source> + <translation><numerusform>dozori po %n najdenem bloku</numerusform><numerusform>dozori po %n najdenih blokih</numerusform><numerusform>dozori po %n najdenih blokih</numerusform><numerusform>dozori po %n najdenih blokih</numerusform></translation> + </message> + <message> <source>not accepted</source> <translation>ni bilo sprejeto</translation> </message> <message> <source>Debit</source> - <translation>Dolg</translation> + <translation>Debit</translation> + </message> + <message> + <source>Total debit</source> + <translation>Skupaj v breme</translation> + </message> + <message> + <source>Total credit</source> + <translation>Skupaj v dobro</translation> </message> <message> <source>Transaction fee</source> @@ -1728,7 +2398,7 @@ Naslov: %4 </message> <message> <source>Net amount</source> - <translation>Neto količina</translation> + <translation>Neto znesek</translation> </message> <message> <source>Message</source> @@ -1747,8 +2417,12 @@ Naslov: %4 <translation>Trgovec</translation> </message> <message> + <source>Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source> + <translation>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.</translation> + </message> + <message> <source>Debug information</source> - <translation>Razhroščevalna informacija</translation> + <translation>Razhroščevalne informacije</translation> </message> <message> <source>Transaction</source> @@ -1756,11 +2430,11 @@ Naslov: %4 </message> <message> <source>Inputs</source> - <translation>Vnosi</translation> + <translation>Vhodi</translation> </message> <message> <source>Amount</source> - <translation>Količina</translation> + <translation>Znesek</translation> </message> <message> <source>true</source> @@ -1774,6 +2448,10 @@ Naslov: %4 <source>, has not been successfully broadcast yet</source> <translation>, še ni bila uspešno raznešena</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Odprto še %n blok</numerusform><numerusform>Odprto še %n bloka</numerusform><numerusform>Odprto še %n bloke</numerusform><numerusform>Odprto še %n blokov</numerusform></translation> + </message> <message> <source>unknown</source> <translation>neznano</translation> @@ -1787,7 +2465,7 @@ Naslov: %4 </message> <message> <source>This pane shows a detailed description of the transaction</source> - <translation>To podokno prikazuje podroben opis transakcije</translation> + <translation>V tem podoknu so prikazane podrobnosti o transakciji</translation> </message> </context> <context> @@ -1801,12 +2479,16 @@ Naslov: %4 <translation>Vrsta</translation> </message> <message> - <source>Address</source> - <translation>Naslov</translation> + <source>Immature (%1 confirmations, will be available after %2)</source> + <translation>Nedozorelo (št. potrditev: %1, na voljo šele po: %2)</translation> + </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Odprto še %n blok</numerusform><numerusform>Odprto še %n bloka</numerusform><numerusform>Odprto še %n bloke</numerusform><numerusform>Odprto še %n blokov</numerusform></translation> </message> <message> <source>Open until %1</source> - <translation>Odpri enoto %1</translation> + <translation>Odprto do %1</translation> </message> <message> <source>Confirmed (%1 confirmations)</source> @@ -1821,28 +2503,48 @@ Naslov: %4 <translation>Generirano, toda ne sprejeto</translation> </message> <message> + <source>Offline</source> + <translation>Brez povezave</translation> + </message> + <message> + <source>Label</source> + <translation>Oznaka</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Nepotrjeno</translation> </message> <message> + <source>Confirming (%1 of %2 recommended confirmations)</source> + <translation>V potrjevanju (št. potrditev: %1 od priporočenih %2)</translation> + </message> + <message> + <source>Conflicted</source> + <translation>V konfliktu</translation> + </message> + <message> <source>Received with</source> - <translation>Prejeto z</translation> + <translation>Prejemek</translation> </message> <message> <source>Received from</source> - <translation>Prejeto od</translation> + <translation>Prejemek</translation> </message> <message> <source>Sent to</source> - <translation>Poslano</translation> + <translation>Izdatek</translation> </message> <message> <source>Payment to yourself</source> - <translation>Izplačilo sebi</translation> + <translation>Nakazilo sebi</translation> </message> <message> <source>Mined</source> - <translation>Minirano</translation> + <translation>Narudarjeno</translation> + </message> + <message> + <source>watch-only</source> + <translation>opazovano</translation> </message> <message> <source>(n/a)</source> @@ -1861,12 +2563,16 @@ Naslov: %4 <translation>Vrsta transakcije.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Naslov prejemnika transakcije.</translation> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Ali je v transakciji udeležen kateri od opazovanih naslovov.</translation> + </message> + <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Uporabniško določen namen transakcije.</translation> </message> <message> <source>Amount removed from or added to balance.</source> - <translation>Količina odlita ali prilita dobroimetju.</translation> + <translation>Znesek spremembe stanja sredstev.</translation> </message> </context> <context> @@ -1901,19 +2607,19 @@ Naslov: %4 </message> <message> <source>Received with</source> - <translation>Prejeto z</translation> + <translation>Prejemek</translation> </message> <message> <source>Sent to</source> - <translation>Poslano</translation> + <translation>Izdatek</translation> </message> <message> <source>To yourself</source> - <translation>Samemu sebi</translation> + <translation>Nakazilo sebi</translation> </message> <message> <source>Mined</source> - <translation>Minirano</translation> + <translation>Narudarjeno</translation> </message> <message> <source>Other</source> @@ -1921,11 +2627,11 @@ Naslov: %4 </message> <message> <source>Enter address or label to search</source> - <translation>Vnesite naslov ali oznako za iskanje</translation> + <translation>Iščite po naslovu ali oznaki</translation> </message> <message> <source>Min amount</source> - <translation>Minimalna količina</translation> + <translation>Minimalni znesek</translation> </message> <message> <source>Copy address</source> @@ -1937,7 +2643,7 @@ Naslov: %4 </message> <message> <source>Copy amount</source> - <translation>Kopiraj količino</translation> + <translation>Kopiraj znesek</translation> </message> <message> <source>Copy transaction ID</source> @@ -1952,8 +2658,20 @@ Naslov: %4 <translation>Prikaži podrobnosti transakcije</translation> </message> <message> + <source>Export Transaction History</source> + <translation>Izvoz zgodovine transakcij</translation> + </message> + <message> + <source>Watch-only</source> + <translation>Opazovano</translation> + </message> + <message> <source>Exporting Failed</source> - <translation>Neuspešen izvoz</translation> + <translation>Seznama transakcij ni bilo mogoče izvoziti.</translation> + </message> + <message> + <source>There was an error trying to save the transaction history to %1.</source> + <translation>Prišlo je do napake med shranjevanjem zgodovine transakcij v datoteko %1.</translation> </message> <message> <source>Exporting Successful</source> @@ -1961,7 +2679,7 @@ Naslov: %4 </message> <message> <source>The transaction history was successfully saved to %1.</source> - <translation>Zgodovina poteklih transakcij je bila uspešno shranjena na %1.</translation> + <translation>Zgodovina poteklih transakcij je bila uspešno shranjena v datoteko %1.</translation> </message> <message> <source>Comma separated file (*.csv)</source> @@ -2002,15 +2720,23 @@ Naslov: %4 </context> <context> <name>UnitDisplayStatusBarControl</name> - </context> + <message> + <source>Unit to show amounts in. Click to select another unit.</source> + <translation>Merska enota za prikaz zneskov. Kliknite za izbiro druge enote.</translation> + </message> +</context> <context> <name>WalletFrame</name> - </context> + <message> + <source>No wallet has been loaded.</source> + <translation>Denarnica ni bila naložena.</translation> + </message> +</context> <context> <name>WalletModel</name> <message> <source>Send Coins</source> - <translation>Pošlji kovance</translation> + <translation>Pošlji</translation> </message> </context> <context> @@ -2021,11 +2747,11 @@ Naslov: %4 </message> <message> <source>Export the data in the current tab to a file</source> - <translation>Izvozi podatke v trenutni zavih v datoteko</translation> + <translation>Izvozi podatke iz trenutnega zavihka v datoteko</translation> </message> <message> <source>Backup Wallet</source> - <translation>Napravi varnostno kopijo denarnice</translation> + <translation>Izdelava varnostne kopije denarnice</translation> </message> <message> <source>Wallet Data (*.dat)</source> @@ -2033,19 +2759,19 @@ Naslov: %4 </message> <message> <source>Backup Failed</source> - <translation>Varnostna kopijo neuspešna</translation> + <translation>Varnostne kopije ni bilo mogoče izdelati.</translation> </message> <message> <source>There was an error trying to save the wallet data to %1.</source> - <translation>Prišlo je do napake pri shranjevanju podatkov denarnice na %1.</translation> + <translation>Prišlo je do napake pri shranjevanju podatkov denarnice v datoteko %1.</translation> </message> <message> <source>The wallet data was successfully saved to %1.</source> - <translation>Podatki denarnice so bili uspešno shranjena na %1.</translation> + <translation>Podatki iz denarnice so bili uspešno shranjeni v datoteko %1.</translation> </message> <message> <source>Backup Successful</source> - <translation>Varnostna kopija uspešna</translation> + <translation>Varnostna kopija je bila uspešno izdelana</translation> </message> </context> <context> @@ -2056,11 +2782,11 @@ Naslov: %4 </message> <message> <source>Specify data directory</source> - <translation>Določi podatkovni imenik</translation> + <translation>Izberite podatkovno mapo</translation> </message> <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> - <translation>Povežite se z vozliščem za pridobitev naslovov uporabnikov in nato prekinite povezavo.</translation> + <translation>Povežite se z vozliščem za pridobitev naslovov soležnikov in nato prekinite povezavo.</translation> </message> <message> <source>Specify your own public address</source> @@ -2068,7 +2794,7 @@ Naslov: %4 </message> <message> <source>Accept command line and JSON-RPC commands</source> - <translation>Sprejmi ukaze iz ukazne vrstice in JSON-RPC</translation> + <translation>Sprejemaj ukaze iz ukazne vrstice in preko JSON-RPC</translation> </message> <message> <source>Run in the background as a daemon and accept commands</source> @@ -2079,16 +2805,72 @@ Naslov: %4 <translation>Uporabi testno omrežje</translation> </message> <message> + <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> + <translation>Sprejemaj zunanje povezave (privzeto: 1, razen če ste vklopili opciji -proxy ali -connect)</translation> + </message> + <message> + <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> + <translation>Veži dani naslov in tam vedno poslušaj. Za naslove protokola IPv6 uporabite zapis [gostitelj]:vrata.</translation> + </message> + <message> + <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> + <translation>Distribuirano v okviru programske licence MIT. Podrobnosti so navedene v priloženi datoteki COPYING ali na naslovu <http://www.opensource.org/licenses/mit-license.php>.</translation> + </message> + <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Izvedi ukaz, ko bo transakcija denarnice se spremenila (V cmd je bil TxID zamenjan za %s)</translation> </message> <message> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Največji še veljavni skupni znesek provizij pri transakcijah z uporabo ene denarnice. Prenizka nastavitev lahko povzroči izločitev večjih transakcij (privzeto %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Omogoči obrezovanje (brisanje) starejših blokov in s tem prihrani pri prostoru za shranjevanje. Ta način delovanja onemogoči uporabo denarnice in ni združljivo z opcijo -txindex. Opozorilo: Če kasneje to opcijo povrnete na privzeto vrednost, boste morali ponovno prenesti celotno verigo. (privzeto: 0 = onemogoči obrezovanje, >%u = ciljna velikost datotek blokov v MiB)</translation> + </message> + <message> + <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> + <translation>Nastavi število niti za preverjanje skript (%u do %d, 0 = samodejno, <0 toliko procesorskih jeder naj ostane prostih, privzeto: %d)</translation> + </message> + <message> <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source> - <translation>To je pred izdana poizkusna verzija - uporaba na lastno odgovornost - ne uporabljajte je za rudarstvo ali trgovske aplikacije</translation> + <translation>To je preizkusna različica še neizdanega programa. Uporabljate jo na lastno odgovornost. Programa ne uporabljajte je za rudarjenje ali trgovske aplikacije.</translation> + </message> + <message> + <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source> + <translation>Na tem računalniku ni bilo mogoče vezati naslova %s. Odjemalec Bitcoin Core je verjetno že zagnan.</translation> + </message> + <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>OPOZORILO: Generirano je bilo nenavadno veliko število blokov. Št. prejetih blokov: %d v št. ur: %d (pričakovanih je %d blokov)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>OPOZORILO: Preverite vašo omrežno povezavo. Št. prejetih blokov: %d v št. ur: %d (pričakovanih je %d blokov)</translation> + </message> + <message> + <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> + <translation>Opozorilo: Vrednost opcije -paytxfee je zelo visoka. To je provizija, ki jo boste plačali, če izvedete plačilo.</translation> + </message> + <message> + <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> + <translation>Opozorilo: Trenutno na omrežju ni videti konsenza! Videti je, kot da bi imeli nekateri rudarji težave.</translation> + </message> + <message> + <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source> + <translation>Opozorilo: Trenutno se s soležniki ne strinjam v popolnosti! Mogoče bi morali vi ali drugi udeleženci posodobiti odjemalce.</translation> </message> <message> <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> - <translation>Opozorilo: napaka pri branju wallet.dat! Vsi ključi so bili pravilno prebrani, podatki o transakciji ali imenik vnešenih naslovov so morda izgubljeni ali nepravilni.</translation> + <translation>Opozorilo: napaka pri branju datoteke wallet.dat! Vsi ključi so bili pravilno prebrani, podatki o transakciji ali imenik vnešenih naslovov so morda izgubljeni ali nepravilni.</translation> + </message> + <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Sprejemaj povezave samo od soležnikov, ki so na naslovih, ki ustrezajo navedeni omrežni maski ali naslovu. Opcijo lahko navedete večkrat.</translation> </message> <message> <source>(default: 1)</source> @@ -2099,76 +2881,328 @@ Naslov: %4 <translation><category> je lahko:</translation> </message> <message> + <source>Attempt to recover private keys from a corrupt wallet.dat</source> + <translation>Skušaj obnoviti zasebne ključe iz okvarjene datoteke wallet.dat</translation> + </message> + <message> <source>Block creation options:</source> <translation>Možnosti ustvarjanja blokov:</translation> </message> <message> + <source>Connect only to the specified node(s)</source> + <translation>Poveži se samo z (enim ali več) navedenimi vozlišči</translation> + </message> + <message> + <source>Connection options:</source> + <translation>Izbire povezave:</translation> + </message> + <message> + <source>Corrupted block database detected</source> + <translation>Podatkovna baza blokov je okvarjena</translation> + </message> + <message> + <source>Debugging/Testing options:</source> + <translation>Možnosti razhroščevanja in testiranja:</translation> + </message> + <message> + <source>Do not load the wallet and disable wallet RPC calls</source> + <translation>Ne naloži denarnice in onemogoči s tem povezane klice RPC</translation> + </message> + <message> + <source>Do you want to rebuild the block database now?</source> + <translation>Želite zdaj obnoviti podatkovno bazo blokov?</translation> + </message> + <message> + <source>Error initializing block database</source> + <translation>Napaka pri inicializaciji podatkovne baze blokov</translation> + </message> + <message> + <source>Error initializing wallet database environment %s!</source> + <translation>Napaka pri inicializaciji okolja podatkovne baze denarnice %s!</translation> + </message> + <message> + <source>Error loading block database</source> + <translation>Napaka pri nalaganju podatkovne baze blokov</translation> + </message> + <message> + <source>Error opening block database</source> + <translation>Napaka pri odpiranju podatkovne baze blokov</translation> + </message> + <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Napaka: Med izvajanjem je prišlo do nepopravljive napake. Podrobnosti so v datoteki debug.log</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Opozorilo: Premalo prostora na disku!</translation> </message> <message> + <source>Failed to listen on any port. Use -listen=0 if you want this.</source> + <translation>Ni mogoče poslušati na nobenih vratih. Če to zares želite, uporabite opcijo -listen=0.</translation> + </message> + <message> + <source>If <category> is not supplied, output all debugging information.</source> + <translation>Če element <category> ni naveden, izpisuje vse informacije za razhroščevanje.</translation> + </message> + <message> <source>Importing...</source> - <translation>Uvažam...</translation> + <translation>Uvažam ...</translation> + </message> + <message> + <source>Incorrect or no genesis block found. Wrong datadir for network?</source> + <translation>Izvornega bloka ni mogoče najti ali pa je neveljaven. Preverite, če ste izbrali pravo podatkovno mapo za izbrano omrežje.</translation> + </message> + <message> + <source>Invalid -onion address: '%s'</source> + <translation>Neveljaven naslov tipa -onion: '%s'</translation> + </message> + <message> + <source>Not enough file descriptors available.</source> + <translation>Na voljo ni dovolj deskriptorjev datotek.</translation> + </message> + <message> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>Povezuj se samo z vozlišči na omrežju tipa <net> (IPv4, IPv6 ali onion)</translation> + </message> + <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>Negativne vrednosti parametra funkcije obrezovanja niso sprejemljive.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Funkcija obrezovanja ni združljiva z opcijo -txindex.</translation> + </message> + <message> + <source>Set database cache size in megabytes (%d to %d, default: %d)</source> + <translation>Nastavitev velikosti predpomnilnik podatkovne baze v MiB (%d do %d, privzeto: %d)</translation> + </message> + <message> + <source>Set maximum block size in bytes (default: %d)</source> + <translation>Nastavitev maksimalne velikosti bloka v bajtih (privzeto: %d)</translation> + </message> + <message> + <source>Specify wallet file (within data directory)</source> + <translation>Ime datoteke z denarnico (znotraj podatkovne mape)</translation> + </message> + <message> + <source>Use UPnP to map the listening port (default: %u)</source> + <translation>Uporabi protokol UPnP za preslikavo vrat za poslušanje (privzeto: %u)</translation> + </message> + <message> + <source>Verifying blocks...</source> + <translation>Preverjam celovitost blokov ...</translation> + </message> + <message> + <source>Verifying wallet...</source> + <translation>Preverjam celovitost denarnice ...</translation> + </message> + <message> + <source>Wallet %s resides outside data directory %s</source> + <translation>Datoteka %s z denarnico se nahaja izven podatkovne mape %s</translation> + </message> + <message> + <source>Wallet options:</source> + <translation>Izbire denarnice:</translation> + </message> + <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Opozorilo: Različica vašega odjemalca je zastarela. Potrebna je nadgradnja!</translation> + </message> + <message> + <source>You need to rebuild the database using -reindex to change -txindex</source> + <translation>Ob spremembi vrednosti opcije -txindex boste morali obnoviti bazo podatkov z uporabo opcije -reindex</translation> + </message> + <message> + <source>Imports blocks from external blk000??.dat file</source> + <translation>Uvozi bloke iz zunanje datoteke blk000??.dat</translation> + </message> + <message> + <source>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</source> + <translation>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.</translation> + </message> + <message> + <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> + <translation>Prišlo je do napake med zagonom poslušalca RPC na naslovu %s in vratih %u: %s</translation> + </message> + <message> + <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> + <translation>Veži dani naslov in sprejemaj povezave samo od navedenih soležnikov. Za naslove protokola IPv6 uporabite zapis [gostitelj]:vrata.</translation> + </message> + <message> + <source>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)</source> + <translation>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)</translation> + </message> + <message> + <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> + <translation>Ne morem zakleniti podatkovne mape %s. Bitcoin Core je verjetno že zagnan.</translation> + </message> + <message> + <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> + <translation>Ustvarjaj nove datoteke s privzetimi sistemskimi dovoljenji, namesto z umask 077. (To pride v poštev samo, kadar imate izklopljeno funkcijo denarnice.)</translation> + </message> + <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Odkrij svoj naslov IP (privzeto: 1, če poslušate in sta opciji -externalip in -proxy neaktivni)</translation> + </message> + <message> + <source>Error: Listening for incoming connections failed (listen returned error %s)</source> + <translation>Napaka: Ni mogoče sprejemati dohodnih povezav (vrnjena napaka: %s)</translation> + </message> + <message> + <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Napaka: Navedli ste nepodprto vrednost opcije -socks. Različice protokola SOCKS ni več mogoče navesti, podprti so samo posredniški strežniki tipa SOCKS5.</translation> + </message> + <message> + <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source> + <translation>Ko bo prejeto ustrezno opozorilo, ali ko bo opažena zelo dolga razvejitev, izvedi navedeni ukazni niz. (Niz %s bo nadomeščen z vsebino sporočila.)</translation> + </message> + <message> + <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> + <translation>Provizije (v BTC/KiB), ki so manjše od te vrednosti, se pri posredovanju smatrajo za nične (privzeto: %s)</translation> + </message> + <message> + <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> + <translation>Če opcija -paytxfee ni nastavljena, nastavi znesek provizije tako visoko, da bodo transakcije potrjene v povprečno n blokih. (privzeto: %u)</translation> + </message> + <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Na vsak posredniški strežnik se prijavi z drugimi naključnimi podatki. Tako je omogočena osamitev tokov v omrežju Tor (privzeto: %u)</translation> + </message> + <message> + <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Opozorilo: Preverite, če sta datum in ura na vašem računalniku točna! Bitcoin Core ne bo dobro deloval, če je nastavljeni čas nepravilen.</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(privzeto: %u)</translation> + </message> + <message> + <source>Activating best chain...</source> + <translation>Preklapljam na najboljšo verigo ...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Če je omogočena funkcija obrezovanja, ni mogoče uporabljati denarnice.</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Naslova %s, podanega pri opciji -whitebind ni mogoče razrešiti.</translation> + </message> + <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Ob zagonu pozovi uporabnika, naj izbere podatkovno mapo (privzeto: 0)</translation> + </message> + <message> + <source>Connect through SOCKS5 proxy</source> + <translation>Poveži se preko posredniškega strežnika SOCKS5</translation> + </message> + <message> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>Copyright (C) 2009-%i The Bitcoin Core Developers</translation> + </message> + <message> + <source>Could not parse -rpcbind value %s as network address</source> + <translation>Vrednost %s opcije -rpcbind ni prepoznaven omrežni naslov</translation> </message> <message> <source>Information</source> <translation>Informacije</translation> </message> <message> + <source>Need to specify a port with -whitebind: '%s'</source> + <translation>Pri opciji -whitebind morate navesti vrata: %s</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Pošlji sledilne/razhroščevalne informacije v konzolo namesto jih shraniti v debug.log datoteko</translation> + <translation>Pošilja sledilne/razhroščevalne informacije na konzolo namesto v datoteko debug.log</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Nastavi korenske certifikate SSL za preverjanje zahtevkov za plačilo (privzeto: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Nastavi jezik, npr. "sl_SI" (privzeto: jezik sistema)</translation> + </message> + <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Ob zagonu prikaži uvodni zaslon (privzeto: 1)</translation> + </message> + <message> + <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> + <translation>Ob zagonu skrajšaj datoteko debug.log (privzeto: 1, če ni vklopljena opcija -debug)</translation> </message> <message> <source>Signing transaction failed</source> - <translation>Podpisovanje transakcije spodletelo</translation> + <translation>Transakcije ni bilo mogoče podpisati.</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Zaženi v minimiranem oknu</translation> + </message> + <message> + <source>This is experimental software.</source> + <translation>Program je eksperimentalne narave.</translation> </message> <message> <source>Transaction amount too small</source> - <translation>Količina transakcije je pramajhna</translation> + <translation>Znesek je pramajhen</translation> </message> <message> <source>Transaction amounts must be positive</source> - <translation>Količina transkacije mora biti pozitivna</translation> + <translation>Znesek mora biti pozitiven</translation> </message> <message> <source>Transaction too large</source> <translation>Transkacija je prevelika</translation> </message> <message> + <source>UI Options:</source> + <translation>Možnosti uporabniškega vmesnika:</translation> + </message> + <message> + <source>Unable to bind to %s on this computer (bind returned error %s)</source> + <translation>Na tem računalniku ni bilo mogoče vezati naslova %s (vrnjena napaka: %s)</translation> + </message> + <message> <source>Username for JSON-RPC connections</source> - <translation>Uporabniško ime za JSON-RPC povezave</translation> + <translation>Uporabniško ime za povezave na JSON-RPC</translation> </message> <message> <source>Warning</source> <translation>Opozorilo</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Opozorilo: ta različica je zastarela, potrebna je nadgradnja!</translation> + <source>Zapping all transactions from wallet...</source> + <translation>Brišem vse transakcije iz denarnice ...</translation> + </message> + <message> + <source>on startup</source> + <translation>ob zagonu</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> - <translation>wallet.dat poškodovana, neuspešna obnova</translation> + <translation>Datoteka wallet.dat je poškodovana in je ni bilo mogoče obnoviti.</translation> </message> <message> <source>Password for JSON-RPC connections</source> - <translation>Geslo za JSON-RPC povezave</translation> + <translation>Geslo za povezave na JSON-RPC</translation> </message> <message> <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source> - <translation>Izvedi ukaz, ko je najboljši blok spremenjen (%s je v cmd zamenjan za iskalnik blokov)</translation> + <translation>Izvedi ukaz, ko je najden najboljši blok (niz %s v ukazu bo zamenjan s hash vrednostjo bloka)</translation> </message> <message> <source>Upgrade wallet to latest format</source> - <translation>Posodobi denarnico v najnovejši zapis</translation> + <translation>Nadgradi denarnico na najnovejšo različico</translation> </message> <message> <source>Rescan the block chain for missing wallet transactions</source> - <translation>Ponovno preglej verigo blokov za manjkajoče transakcije denarnice</translation> + <translation>S ponovnim pregledom verige blokov poišči manjkajoče transakcije iz denarnice</translation> </message> <message> <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Uporabi OpenSSL (https) za JSON-RPC povezave</translation> + <translation>Uporabi OpenSSL (https) za povezave na JSON-RPC</translation> </message> <message> <source>This help message</source> @@ -2176,23 +3210,59 @@ Naslov: %4 </message> <message> <source>Allow DNS lookups for -addnode, -seednode and -connect</source> - <translation>Omogoči DNS poizvedbe za -addnode, -seednode in -connect.</translation> + <translation>Omogoči poizvedbe DNS za opcije -addnode, -seednode in -connect.</translation> </message> <message> <source>Loading addresses...</source> - <translation>Nalaganje naslovov ...</translation> + <translation>Nalagam naslove ...</translation> </message> <message> <source>Error loading wallet.dat: Wallet corrupted</source> <translation>Napaka pri nalaganju wallet.dat: denarnica pokvarjena</translation> </message> <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Za dostop do soležnikov preko skritih storitev Tor uporabi drug posredniški strežnik SOCKS5 (privzeto: %s)</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(privzeto: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Sprejemljivi tipi šifriranja (privzeto: %s)</translation> + </message> + <message> <source>Error loading wallet.dat</source> <translation>Napaka pri nalaganju wallet.dat</translation> </message> <message> <source>Invalid -proxy address: '%s'</source> - <translation>Neveljaven -proxy naslov: '%s'</translation> + <translation>Neveljaven naslov -proxy: '%s'</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <translation>Posreduj transakcije tipa multisig, ki niso hkrati tipa P2SH. (privzeto: %u)</translation> + </message> + <message> + <source>Specify configuration file (default: %s)</source> + <translation>Za shranjevanje konfiguracije uporabi navedeno datoteko. (privzeto: %s)</translation> + </message> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Vzpostavljanje nove povezave poteče po navedenem št. pretečenih milisekund. (najmanj: 1, privzeto: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Za shranjevanje PID uporabi navedeno datoteko. (privzeto: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <translation>Pri odlivnih transakcijah omogoči trošenje drobiža iz še nepotrjenih plačil (privzeto: %u)</translation> + </message> + <message> + <source>Threshold for disconnecting misbehaving peers (default: %u)</source> + <translation>Prekini povezavo s soležnikom, ko št. njegovih kazenskih točk preseže navedeni prag. (privzeto: %u)</translation> </message> <message> <source>Unknown network specified in -onlynet: '%s'</source> @@ -2200,11 +3270,11 @@ Naslov: %4 </message> <message> <source>Cannot resolve -bind address: '%s'</source> - <translation>Nemogoče rešiti -bind naslova: '%s'</translation> + <translation>Naslova %s, podanega pri opciji -bind ni mogoče razrešiti.</translation> </message> <message> <source>Cannot resolve -externalip address: '%s'</source> - <translation>Nemogoče rešiti -externalip naslova: '%s'</translation> + <translation>Naslova "%s", podanega pri opciji -externalip ni mogoče razrešiti.</translation> </message> <message> <source>Invalid amount for -paytxfee=<amount>: '%s'</source> @@ -2216,15 +3286,15 @@ Naslov: %4 </message> <message> <source>Loading block index...</source> - <translation>Nalaganje indeksa blokov ...</translation> + <translation>Nalagam kazalo blokov ...</translation> </message> <message> <source>Add a node to connect to and attempt to keep the connection open</source> - <translation>Dodaj vozlišče za povezavo nanj in skušaj le to obdržati odprto</translation> + <translation>Dodaj povezavo na vozlišče in jo skušaj držati odprto</translation> </message> <message> <source>Loading wallet...</source> - <translation>Nalaganje denarnice ...</translation> + <translation>Nalagam denarnico ...</translation> </message> <message> <source>Cannot downgrade wallet</source> @@ -2236,7 +3306,7 @@ Naslov: %4 </message> <message> <source>Rescanning...</source> - <translation>Ponovno pregledovanje ...</translation> + <translation>Ponovno pregledujem verigo ...</translation> </message> <message> <source>Done loading</source> diff --git a/src/qt/locale/bitcoin_sq.ts b/src/qt/locale/bitcoin_sq.ts index 82c0a61701..6ed9856889 100644 --- a/src/qt/locale/bitcoin_sq.ts +++ b/src/qt/locale/bitcoin_sq.ts @@ -1,4 +1,4 @@ -<TS language="sq" version="2.1"> +<TS language="sq" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -46,14 +46,38 @@ <translation>Duke marr adresen</translation> </message> <message> + <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> + <translation>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.</translation> + </message> + <message> + <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> + <translation>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.</translation> + </message> + <message> + <source>Copy &Label</source> + <translation>Kopjo &Etiketë</translation> + </message> + <message> <source>&Edit</source> <translation>&Ndrysho</translation> </message> <message> + <source>Export Address List</source> + <translation>Eksporto listën e adresave</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Skedar i ndarë me pikëpresje(*.csv)</translation> </message> - </context> + <message> + <source>Exporting Failed</source> + <translation>Eksportimi dështoj</translation> + </message> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Gabim gjatë ruajtjes së listës së adresave në %1. Ju lutem provoni prapë.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -108,10 +132,6 @@ <translation>Ndrysho frazkalimin</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Futni frazkalimin e vjetër dhe të ri në portofol. </translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Konfirmoni enkriptimin e portofolit</translation> </message> @@ -226,26 +246,10 @@ <source>&About Bitcoin Core</source> <translation>Rreth Berthames Bitkoin</translation> </message> - <message numerus="yes"> - <source>%n hour(s)</source> - <translation><numerusform>%n ore</numerusform><numerusform>%n ore</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n day(s)</source> - <translation><numerusform>%n dite</numerusform><numerusform>%n dite</numerusform></translation> - </message> - <message numerus="yes"> - <source>%n week(s)</source> - <translation><numerusform>%n jave</numerusform><numerusform>%n jave</numerusform></translation> - </message> <message> <source>%1 and %2</source> <translation>%1 dhe %2</translation> </message> - <message numerus="yes"> - <source>%n year(s)</source> - <translation><numerusform>%n vit</numerusform><numerusform>%n vite</numerusform></translation> - </message> <message> <source>%1 behind</source> <translation>%1 Pas</translation> @@ -649,10 +653,6 @@ <translation>Lloji</translation> </message> <message> - <source>Address</source> - <translation>Adresë</translation> - </message> - <message> <source>Open until %1</source> <translation>Hapur deri më %1</translation> </message> @@ -669,6 +669,10 @@ <translation>I krijuar por i papranuar</translation> </message> <message> + <source>Label</source> + <translation>Etiketë</translation> + </message> + <message> <source>Received with</source> <translation>Marrë me</translation> </message> @@ -708,6 +712,10 @@ <translation>Kopjo adresën</translation> </message> <message> + <source>Exporting Failed</source> + <translation>Eksportimi dështoj</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Skedar i ndarë me pikëpresje(*.csv)</translation> </message> diff --git a/src/qt/locale/bitcoin_sr.ts b/src/qt/locale/bitcoin_sr.ts index 842b3f90ab..ddaab9ab2b 100644 --- a/src/qt/locale/bitcoin_sr.ts +++ b/src/qt/locale/bitcoin_sr.ts @@ -1,4 +1,4 @@ -<TS language="sr" version="2.1"> +<TS language="sr" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -88,10 +88,6 @@ <translation>Промена лозинке</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Унесите стару и нову лозинку за шифровање новчаника.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Одобрите шифровање новчаника</translation> </message> @@ -108,10 +104,6 @@ <translation>Новчаник је шифрован</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin će se sad zatvoriti da bi završio proces enkripcije. Zapamti da enkripcija tvog novčanika ne može u potpunosti da zaštiti tvoje bitcoine da ne budu ukradeni od malawarea koji bi inficirao tvoj kompjuter.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>Неуспело шифровање новчаника</translation> </message> @@ -199,10 +191,6 @@ <translation>Пошаљите новац на bitcoin адресу</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Изаберите могућности bitcoin-а</translation> - </message> - <message> <source>Change the passphrase used for wallet encryption</source> <translation>Мењање лозинке којом се шифрује новчаник</translation> </message> @@ -247,14 +235,6 @@ <translation>Придошла трансакција</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Datum: %1⏎ Iznos: %2⏎ Tip: %3⏎ Adresa: %4⏎</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Новчаник јс <b>шифрован</b> и тренутно <b>откључан</b></translation> </message> @@ -565,10 +545,6 @@ Address: %4 <translation>tip</translation> </message> <message> - <source>Address</source> - <translation>Адреса</translation> - </message> - <message> <source>Open until %1</source> <translation>Otvoreno do %1</translation> </message> @@ -585,6 +561,10 @@ Address: %4 <translation>Generisan ali nije prihvaćen</translation> </message> <message> + <source>Label</source> + <translation>Етикета</translation> + </message> + <message> <source>Received with</source> <translation>Primljen sa</translation> </message> @@ -621,10 +601,6 @@ Address: %4 <translation>Tip transakcije</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Destinacija i adresa transakcije</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Iznos odbijen ili dodat balansu.</translation> </message> diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index 0ed914fdcf..0139154019 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -1,4 +1,4 @@ -<TS language="sv" version="2.1"> +<TS language="sv" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -67,11 +67,11 @@ </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>Detta är dina Bitcoin adresser för att skicka betalningar. Kolla alltid summan och den mottagande adressen innan du skickar Bitcoins.</translation> + <translation>Detta är dina Bitcoin-adresser för att skicka betalningar. Kolla alltid summan och den mottagande adressen innan du skickar Bitcoins.</translation> </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> - <translation>Detta är dina Bitcoin adresser för att ta emot betalningar. Det rekommenderas att använda en ny mottagningsadress för varje transaktion.</translation> + <translation>Detta är dina Bitcoin-adresser för att ta emot betalningar. Det rekommenderas att använda en ny mottagningsadress för varje transaktion.</translation> </message> <message> <source>Copy &Label</source> @@ -79,7 +79,7 @@ </message> <message> <source>&Edit</source> - <translation>&Editera</translation> + <translation>&Ändra</translation> </message> <message> <source>Export Address List</source> @@ -111,14 +111,14 @@ Var vänlig och försök igen.</translation> </message> <message> <source>(no label)</source> - <translation>(Ingen etikett)</translation> + <translation>(ingen etikett)</translation> </message> </context> <context> <name>AskPassphraseDialog</name> <message> <source>Passphrase Dialog</source> - <translation>Lösenords Dialog</translation> + <translation>Lösenordsdialog</translation> </message> <message> <source>Enter passphrase</source> @@ -157,10 +157,6 @@ Var vänlig och försök igen.</translation> <translation>Ändra lösenord</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Ange plånbokens gamla och nya lösenord.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Bekräfta kryptering av plånbok</translation> </message> @@ -173,6 +169,10 @@ Var vänlig och försök igen.</translation> <translation>Är du säker på att du vill kryptera din plånbok?</translation> </message> <message> + <source>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.</source> + <translation>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.</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -189,8 +189,8 @@ Var vänlig och försök igen.</translation> <translation>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>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Programmet 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.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Ge det gamla lösenordet och det nya lösenordet för plånboken.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -281,7 +281,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>&Change Passphrase...</source> - <translation>&Byt Lösenord...</translation> + <translation>&Byt lösenord...</translation> </message> <message> <source>&Sending addresses...</source> @@ -297,7 +297,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Bitcoin Core client</source> - <translation>Bitcoin Core klient</translation> + <translation>Bitcoin Core-klient</translation> </message> <message> <source>Importing blocks from disk...</source> @@ -312,10 +312,6 @@ Var vänlig och försök igen.</translation> <translation>Skicka bitcoins till en Bitcoin-adress</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Ändra konfigurationsalternativ för Bitcoin</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Säkerhetskopiera plånboken till en annan plats</translation> </message> @@ -325,7 +321,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>&Debug window</source> - <translation>&Debug fönster</translation> + <translation>&Debug-fönster</translation> </message> <message> <source>Open debugging and diagnostic console</source> @@ -389,11 +385,11 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Tabs toolbar</source> - <translation>Verktygsfält för Tabbar</translation> + <translation>Verktygsfält för tabbar</translation> </message> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Kärna</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>Request payments (generates QR codes and bitcoin: URIs)</source> @@ -404,6 +400,10 @@ Var vänlig och försök igen.</translation> <translation>&Om Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Ändra konfigurationsalternativ för Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Visa listan av använda avsändaradresser och etiketter</translation> </message> @@ -421,7 +421,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> - <translation>Visa Bitcoin Core hjälpmeddelande för att få en lista med möjliga Bitcoin kommandoradsalternativ.</translation> + <translation>Visa Bitcoin Cores hjälpmeddelande för att få en lista med möjliga Bitcoin-kommandoradsalternativ.</translation> </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> @@ -432,6 +432,10 @@ Var vänlig och försök igen.</translation> <translation>Ingen block-källa tillgänglig...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Bearbetade %n block av transaktionshistoriken.</numerusform><numerusform>Bearbetade %n block av transaktionshistoriken.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n timme</numerusform><numerusform>%n timmar</numerusform></translation> </message> @@ -457,7 +461,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Last received block was generated %1 ago.</source> - <translation>Senast mottagna block genererades %1 sen.</translation> + <translation>Senast mottagna block genererades för %1 sen.</translation> </message> <message> <source>Transactions after this will not yet be visible.</source> @@ -479,35 +483,49 @@ Var vänlig och försök igen.</translation> <source>Up to date</source> <translation>Uppdaterad</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>Bearbetat %n block av transaktionshistoriken.</numerusform><numerusform>Bearbetat %n block av transaktionshistoriken.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Hämtar senaste...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Transaktion skickad</translation> + <source>Date: %1 +</source> + <translation>Datum: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Inkommande transaktion</translation> + <source>Amount: %1 +</source> + <translation>Belopp: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Datum: %1 -Belopp: %2 -Typ: %3 -Adress: %4 + <translation>Typ: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Etikett: %1 </translation> </message> <message> + <source>Address: %1 +</source> + <translation>Adress: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Transaktion skickad</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Inkommande transaktion</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Denna plånbok är <b>krypterad</b> och för närvarande <b>olåst</b></translation> </message> @@ -535,7 +553,7 @@ Adress: %4 </message> <message> <source>Bytes:</source> - <translation>Antal Byte:</translation> + <translation>Antal byte:</translation> </message> <message> <source>Amount:</source> @@ -563,15 +581,15 @@ Adress: %4 </message> <message> <source>(un)select all</source> - <translation>(av)välj allt</translation> + <translation>(av)markera allt</translation> </message> <message> <source>Tree mode</source> - <translation>Trädmetod</translation> + <translation>Trädvy</translation> </message> <message> <source>List mode</source> - <translation>Listmetod</translation> + <translation>Listvy</translation> </message> <message> <source>Amount</source> @@ -591,7 +609,7 @@ Adress: %4 </message> <message> <source>Confirmations</source> - <translation>Konfirmationer</translation> + <translation>Bekräftelser</translation> </message> <message> <source>Confirmed</source> @@ -698,6 +716,18 @@ Adress: %4 <translation>ingen</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Denna etikett blir röd om transaktionens storlek är större än 1000 bytes.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Denna etikett blir röd om prioriteten är lägre än "medium".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Denna etikett blir röd om någon mottagare får ett belopp mindre än %1.</translation> + </message> + <message> <source>yes</source> <translation>ja</translation> </message> @@ -706,10 +736,6 @@ Adress: %4 <translation>nej</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Denna etikett blir röd om transaktionen överstiger 1000 byte.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Detta betyder att en avgift på minst %1 per kB behövs.</translation> </message> @@ -722,14 +748,6 @@ Adress: %4 <translation>Transaktioner med högre prioritet har större sannolikhet att inkluderas i ett block.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Denna etikett blir röd om prioriteten är mindre än "medium".</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Denna etikett blir röd om någon mottagare får en betalning som är mindre än %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(Ingen etikett)</translation> </message> @@ -746,7 +764,7 @@ Adress: %4 <name>EditAddressDialog</name> <message> <source>Edit Address</source> - <translation>Redigera Adress</translation> + <translation>Redigera adress</translation> </message> <message> <source>&Label</source> @@ -824,7 +842,7 @@ Adress: %4 <name>HelpMessageDialog</name> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Kärna</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>version</source> @@ -850,30 +868,6 @@ Adress: %4 <source>command-line options</source> <translation>kommandoradsalternativ</translation> </message> - <message> - <source>UI options</source> - <translation>UI alternativ</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Ändra språk, till exempel "de_DE" (förvalt: systemets språk)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Starta som minimerad</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Sätt SSL root-certifikat för betalningsbegäran (förvalt: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Visa startbilden vid uppstart (förvalt: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Välj datakatalog vid uppstart (förvalt: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -887,11 +881,11 @@ Adress: %4 </message> <message> <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source> - <translation>Eftersom detta är första gången programmet startas får du välja var Bitcoin Core skall lagra sitt data.</translation> + <translation>Eftersom detta är första gången programmet startas får du välja var Bitcoin Core skall lagra sina data.</translation> </message> <message> <source>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.</source> - <translation>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.</translation> + <translation>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.</translation> </message> <message> <source>Use the default data directory</source> @@ -903,7 +897,7 @@ Adress: %4 </message> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Kärna</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>Error: Specified data directory "%1" cannot be created.</source> @@ -956,14 +950,6 @@ Adress: %4 <translation>&Allmänt</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Starta Bitcoin automatiskt efter inloggning.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Starta Bitcoin vid systemstart</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Storleken på &databascache</translation> </message> @@ -973,7 +959,7 @@ Adress: %4 </message> <message> <source>Number of script &verification threads</source> - <translation>Antalet skript & verifikationstrådar</translation> + <translation>Antalet skript&verifikationstrådar</translation> </message> <message> <source>Accept connections from outside</source> @@ -988,8 +974,16 @@ Adress: %4 <translation>Proxyns IP-adress (t.ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Gränssnittets språk kan väljas här. Denna inställning träder i kraft efter omstart av Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> - <translation>Tredjeparts URL:er (t.ex. en block utforskare) 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 |.</translation> + <translation>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 |.</translation> </message> <message> <source>Third party transaction URLs</source> @@ -997,21 +991,29 @@ Adress: %4 </message> <message> <source>Active command-line options that override above options:</source> - <translation>Aktiva kommandoradsalternativ som överrider alternativen ovan:</translation> + <translation>Aktiva kommandoradsalternativ som ersätter alternativen ovan:</translation> </message> <message> <source>Reset all client options to default.</source> - <translation>Återställ alla klient inställningar till förvalen.</translation> + <translation>Återställ alla klientinställningar till förvalen.</translation> </message> <message> <source>&Reset Options</source> - <translation>&Återställ Alternativ</translation> + <translation>&Återställ alternativ</translation> </message> <message> <source>&Network</source> <translation>&Nätverk</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Kör Bitcoin Core automatiskt vid systeminloggning.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Kör Bitcoin Core vid systeminloggning</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = lämna så många kärnor lediga)</translation> </message> @@ -1025,15 +1027,15 @@ Adress: %4 </message> <message> <source>Enable coin &control features</source> - <translation>Aktivera mynt och kontrollfunktioner</translation> + <translation>Aktivera mynt&kontrollfunktioner</translation> </message> <message> <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source> - <translation>Om du avaktiverar betalning med okonfirmerade växel, kan inte växeln från en transaktion användas förrän den transaktionen har minst en konfirmation.</translation> + <translation>Om du avaktiverar betalning med obekräftad växel, kan inte växeln från en transaktion användas förrän den transaktionen har minst en bekräftelse.</translation> </message> <message> <source>&Spend unconfirmed change</source> - <translation>&Spendera okonfirmerad växel</translation> + <translation>&Spendera obekräftad växel</translation> </message> <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> @@ -1076,10 +1078,6 @@ Adress: %4 <translation>&Minimera till systemfältet istället för aktivitetsfältet</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Minimera applikationen istället för att stänga ner den när fönstret stängs. Detta innebär att programmet fotrsätter att köras tills du väljer Avsluta i menyn.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>M&inimera vid stängning</translation> </message> @@ -1092,16 +1090,12 @@ Adress: %4 <translation>Användargränssnittets &språk: </translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Användargränssnittets språk kan ställas in här. Denna inställning träder i kraft efter en omstart av Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>&Måttenhet att visa belopp i: </translation> </message> <message> <source>Choose the default subdivision unit to show in the interface and when sending coins.</source> - <translation>Välj en måttenhet att visa när du skickar mynt.</translation> + <translation>Välj en måttenhet att visa i gränssnittet och när du skickar mynt.</translation> </message> <message> <source>Whether to show coin control features or not.</source> @@ -1132,8 +1126,8 @@ Adress: %4 <translation>Klientomstart är nödvändig för att aktivera ändringarna.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Klienten skall stängas av, vill du fortsätta?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Programmet kommer att stängas. Vill du fortsätta?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1141,7 +1135,7 @@ Adress: %4 </message> <message> <source>The supplied proxy address is invalid.</source> - <translation>Den medföljande proxy adressen är ogiltig.</translation> + <translation>Den angivna proxy-adressen är ogiltig.</translation> </message> </context> <context> @@ -1218,10 +1212,6 @@ Adress: %4 <source>Current total balance in watch-only addresses</source> <translation>Nuvarande total balans i granska-bara adresser</translation> </message> - <message> - <source>out of sync</source> - <translation>osynkroniserad</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1242,10 +1232,6 @@ Adress: %4 <translation>Betalningsbegärans nätverk matchar inte klientens nätverk.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Tiden för betalningsbegäran gick ut</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Betalningsbegäran är inte initierad.</translation> </message> @@ -1278,10 +1264,18 @@ Adress: %4 <translation>Betalningsbegäransfilen kan inte läsas! Detta kan orsakas av en felaktig betalningsbegäransfil.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Betalningsbegäran löpte ut.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Overifierade betalningsbegärningar till specialbetalningsskript stöds inte.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Ogiltig betalningsbegäran.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Återbetalning från %1</translation> </message> @@ -1321,8 +1315,8 @@ Adress: %4 <translation>Användaragent</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Adress/Värdnamn</translation> + <source>Node/Service</source> + <translation>Nod/Tjänst</translation> </message> <message> <source>Ping Time</source> @@ -1356,14 +1350,6 @@ Adress: %4 <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>NÄTVERK</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>OKÄND</translation> - </message> - <message> <source>None</source> <translation>Ingen</translation> </message> @@ -1454,6 +1440,10 @@ Adress: %4 <translation>Aktuellt antal block</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Öppna felsökningsloggfilen för Bitcoin Core från den nuvarande datakatalogen. Detta kan ta några sekunder om loggfilen är stor.</translation> + </message> + <message> <source>Received</source> <translation>Mottagen</translation> </message> @@ -1522,6 +1512,10 @@ Adress: %4 <translation>Pingtid</translation> </message> <message> + <source>Time Offset</source> + <translation>Tidsförskjutning</translation> + </message> + <message> <source>Last block time</source> <translation>Sista blocktid</translation> </message> @@ -1562,16 +1556,12 @@ Adress: %4 <translation>Debugloggfil</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Öppna Bitcoin debug-loggfilen som finns i datakatalogen. Detta kan ta några sekunder för stora loggfiler.</translation> - </message> - <message> <source>Clear console</source> <translation>Rensa konsollen</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Välkommen till Bitcoin RPC-konsollen.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Välkommen till RPC-konsolen för Bitcoin Core.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1858,14 +1848,6 @@ Adress: %4 <translation>Fäll ihop avgiftsinställningarna</translation> </message> <message> - <source>Minimize</source> - <translation>Minimera</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Om den anpassad avgiften är satt till 1000 satoshi och transaktionen bara är 250 byte, betalar "per kilobyte" bara 250 satoshi i avgift, medans "minst" betalar 1000 satoshi. För transaktioner större än en kilobyte betalar både per kilobyte.</translation> - </message> - <message> <source>per kilobyte</source> <translation>per kilobyte</translation> </message> @@ -1874,6 +1856,10 @@ Adress: %4 <translation>Om den anpassad avgiften är satt till 1000 satoshi och transaktionen bara är 250 byte, betalar "per kilobyte" bara 250 satoshi i avgift, medans "totalt minst" betalar 1000 satoshi. För transaktioner större än en kilobyte betalar både per kilobyte.</translation> </message> <message> + <source>Hide</source> + <translation>Göm</translation> + </message> + <message> <source>total at least</source> <translation>totalt minst</translation> </message> @@ -1994,10 +1980,6 @@ Adress: %4 <translation>eller</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Mottagarens adress är inte giltig, vänligen kontrollera igen.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Det betalade beloppet måste vara större än 0.</translation> </message> @@ -2010,10 +1992,6 @@ Adress: %4 <translation>Totalvärdet överstiger ditt saldo när transaktionsavgiften %1 är pålagd.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Dubblett av adress funnen, kan bara skicka till varje adress en gång per sändning.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Transaktionen gick inte att skapa!</translation> </message> @@ -2022,16 +2000,28 @@ Adress: %4 <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> - <translation>En avgift högre än %1 anses som en onormalt hög avgift.</translation> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>En avgift som är högre än %1 anses vara en orimligt hög avgift.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Betalningsbegäran löpte ut.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Uppskattas till att påbörja bekräftelse inom %n block.</numerusform><numerusform>Uppskattas till att påbörja bekräftelse inom %n block.</numerusform></translation> </message> <message> <source>Pay only the minimum fee of %1</source> <translation>Betala endast den minimala avgiften på %1</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Bekräftelsen beräknas börja inom %1 block.</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Mottagarens adress är ogiltig. Kontrollera igen.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Duplicerad adress upptäckt: adresser skall endast användas en gång var.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2105,12 +2095,20 @@ Adress: %4 <translation>Radera denna post</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>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.</translation> + </message> + <message> <source>Message:</source> <translation>Meddelande:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Detta är en verifierad betalningsbegäran.</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Detta är en oautentiserad betalningsbegäran.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Detta är en autentiserad betalningsbegäran.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2121,10 +2119,6 @@ Adress: %4 <translation>Ett meddelande som bifogades bitcoin-URI, vilket lagras med transaktionen som referens. NB: Meddelandet kommer inte att sändas över Bitcoinnätverket.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Detta är en overifierad betalningsbegäran.</translation> - </message> - <message> <source>Pay To:</source> <translation>Betala Till:</translation> </message> @@ -2155,8 +2149,8 @@ Adress: %4 <translation>&Signera Meddelande</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Du kan signera meddelanden med dina adresser för att bevisa att du äger dem. Var försiktig med vad du signerar eftersom phising-attacker kan försöka få dig att skriva över din identitet till någon annan. Signera bara väldetaljerade påståenden du kan gå i god för.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Du kan underteckna meddelanden/avtal med dina adresser för att bevisa att du kan ta emot bitcoins som skickats till dem. Var försiktig så du inte undertecknar något oklart eller konstigt, eftersom phishing-angrepp kan försöka få dig att underteckna din identitet till dem. Underteckna endast väldetaljerade meddelanden som du godkänner.</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2211,8 +2205,8 @@ Adress: %4 <translation>&Verifiera Meddelande</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Skriv in din adress, meddelande (se till att du kopierar radbrytningar, mellanslag, tabbar, osv. exakt) och signatur nedan för att verifiera meddelandet. Var noga med att inte läsa in mer i signaturen än vad som finns i det signerade meddelandet, för att undvika att luras av en man-in-the-middle attack.</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Ange mottagarens adress, meddelande (kopiera radbrytningar, mellanrum, flikar, etc. exakt) och signatur nedan för att verifiera meddelandet. Undvik att läsa in mera information i signaturen än vad som stod i själva undertecknade meddelandet, för att undvika ett man-in-the-middle-angrepp. Notera att detta endast bevisar att undertecknad tar emot med adressen, det bevisar inte vem som skickat transaktionen!</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2478,10 +2472,6 @@ Adress: %4 <translation>Typ</translation> </message> <message> - <source>Address</source> - <translation>Adress</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Omogen (%1 konfirmeringar, blir tillgänglig efter %2)</translation> </message> @@ -2510,6 +2500,10 @@ Adress: %4 <translation>Nerkopplad</translation> </message> <message> + <source>Label</source> + <translation>Etikett</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Okonfirmerade</translation> </message> @@ -2566,8 +2560,8 @@ Adress: %4 <translation>Anger om granska-bara--adresser är involverade i denna transaktion.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Transaktionens destinationsadress.</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Användardefinierat syfte/ändamål för transaktionen.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2820,16 +2814,16 @@ Adress: %4 <translation>Distribuerad under MIT mjukvarulicens, se den bifogade filen COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Ange regressiontestläge, som använder en speciell kedja i vilka block kan lösas omedelbart.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Exekvera kommando när en plånbokstransaktion ändras (%s i cmd är ersatt av TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>I denna mode kontrollerar -genproclimit hur många block som genereras på en gång.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Maximal total avgift att använda i en plånbokstransaktion. Sätts denna för lågt kommer stora transaktioner att avbrytas (förvalt: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Reducera lagringsbehovet genom att beskära (ta bort) gamla block. Detta läge avaktiverar plånbokssupport och är inkompatibel med -txindex. Varning: Ändras denna inställning måste hela blockkedjan laddas ner igen. 0 = avaktivera beskärning av blocks, >%u = målstorlek i MiB att använda för blockfiler)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2844,6 +2838,14 @@ Adress: %4 <translation>Det går inte att binda till %s på den här datorn. Bitcoin Core är förmodligen redan igång.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>Varning: Onormalt antal block block genererade. %d block mottagna senaste %d timmarna (%d förväntade)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>Varning: Kontrollera din närverksanslutning. %d block mottagna senaste %d timmarna, (%d förväntade)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Varning: -paytxfee är satt väldigt hög! Detta är avgiften du kommer betala för varje transaktion.</translation> </message> @@ -2900,10 +2902,6 @@ Adress: %4 <translation>Avlusnings/Testnings optioner:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Hitta egen IP-adress (förvalt: 1 under lyssning och utan -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Ladda inte plånboken och stäng av RPC-anrop till plånboken</translation> </message> @@ -2964,8 +2962,12 @@ Adress: %4 <translation>Anslut enbart till noder i nätverket <net> (IPv4, IPv6 eller onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Återskapa blockkedjans index från nuvarande blk000??.dat filer</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>Beskärning kan inte konfigureras med ett negativt värde.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Beskärningsläge är inkompatibel med -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2980,10 +2982,6 @@ Adress: %4 <translation>Ange plånboksfil (inom datakatalogen)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Detta är avsett för regressionstestningsverktyg och applikationsutveckling.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Använd UPnP för att mappa den lyssnande porten (förvalt: %u)</translation> </message> @@ -3004,6 +3002,10 @@ Adress: %4 <translation>Plånboksinställningar:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Varning: Denna version är föråldrad; uppgradering krävs!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Du måste återskapa databasen med -reindex för att ändra -txindex</translation> </message> @@ -3032,14 +3034,14 @@ Adress: %4 <translation>Kan inte låsa data-mappen %s. Bitcoin Core körs förmodligen redan.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Antalsbegränsa kontinuerligt fria transaktioner till <n>*1000 bytes per minut (förvalt:%u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>Skapa nya filer med systemets förvalda rättigheter, istället för umask 077 (bara effektivt med avaktiverad plånboks funktionalitet)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Upptäck egna IP adresser (standard: 1 vid lyssning ingen -externalip eller -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Fel: Avlyssning av inkommande anslutningar misslyckades (Avlyssningen returnerade felkod %s)</translation> </message> @@ -3056,10 +3058,6 @@ Adress: %4 <translation>Avgifter (i BTC/Kb) mindre än detta betraktas som nollavgift för vidarebefodran (förvalt: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Avgifter (i BTC/Kb) mindre än detta betraktas som nollavgift för transaktionsskapande (förvalt: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Om paytxfee inte är satt, inkludera tillräcklig avgift så att transaktionen börjar att konfirmeras inom n blocks (förvalt: %u)</translation> </message> @@ -3072,23 +3070,26 @@ Adress: %4 <translation>Maximal storlek på data i databärartransaktioner som vi reläar och bryter (förvalt: %u) </translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>Maximum total avgift att använda i en plånbok transaktion, sätts den för lågt kan stora transaktioner avbrytas (förvalt: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Beskärning konfigurerad under miniminivån %d MB. Var vänlig använd ett högre värde.</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Sök efter klientadresser med DNS sökningen, om det finns otillräckligt med adresser (förvalt: 1 om inte -connect)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>Begär hög-prioritet för relätrafik eller lågavgifts transaktioner -(förvalt: %u)</translation> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Slumpa autentiseringen för varje proxyanslutning. Detta möjliggör Tor ström-isolering (förvalt: %u)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Sätt den maximala storleken av hög-prioriterade/låg-avgifts transaktioner i byte (förvalt: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Transaktionen är för liten att skicka efter det att avgiften har dragits</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -3129,14 +3130,34 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>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 </translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Du måste bygga om databasen genom att använda -reindex för att återgå till obeskärt läge. Detta kommer att ladda ner hela blockkedjan.</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(förvalt: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Acceptera publika REST förfrågningar (förvalt: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Aktiverar bästa kedjan...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Kan inte köra med en plånbok i beskärningsläge.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Kan inte matcha -whitebind adress: '%s'</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Välj datakatalog vid uppstart (förvalt: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Anslut genom SOCKS5 proxy</translation> </message> @@ -3217,12 +3238,12 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>RPC support för HTTP permanent anslutning (förvalt: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Slumpmässigt tappa 1 av varje <n> nåtverksmeddelande</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Återskapa blockkedjans index från nuvarande blk000??.dat filer under uppstarten</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Slupmässigt brus 1 gång varje <n> nätverksmeddelande</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Mottag och visa P2P nätverksvarningar (förvalt: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3233,10 +3254,22 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Sänd transaktioner som nollavgiftstransaktioner om möjligt (förvalt: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Sätt SSL root-certifikat för betalningsbegäran (förvalt: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Ändra språk, till exempel "de_DE" (förvalt: systemets språk)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Visa alla avlusningsoptioner (använd: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Visa startbilden vid uppstart (förvalt: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Krymp debug.log filen vid klient start (förvalt: 1 vid ingen -debug)</translation> </message> @@ -3245,6 +3278,14 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Signering av transaktion misslyckades</translation> </message> <message> + <source>Start minimized</source> + <translation>Starta som minimerad</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Transaktionen är för liten för att betala avgiften</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Detta är experimentmjukvara.</translation> </message> @@ -3265,6 +3306,10 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transaktionen är för stor</translation> </message> <message> + <source>UI Options:</source> + <translation>UI Alternativ:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Det går inte att binda till %s på den här datorn (bind returnerade felmeddelande %s)</translation> </message> @@ -3285,10 +3330,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Varning</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Varning: denna version är föråldrad, uppgradering krävs!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Varning: Argument -benchmark stöds inte och ignoreras, använd -debug=bench.</translation> </message> @@ -3349,18 +3390,10 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = spara tx metadata t.ex. kontoägare och betalningsbegäransinformation, 2 = släng tx metadata)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Töm databasens minnespool till disk varje <n> megabytes (förvalt: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Hur grundlig blockverifikationen vid -checkblocks är (0-4, förvalt: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Logga transaktionsprioritet och avgift per kB vid blockbrytning (förvalt: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Upprätthåll ett fullständigt transaktionsindex, som används av getrawtransaction rpc-anrop (förval: %u)</translation> </message> @@ -3389,18 +3422,10 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Sök alltid efter klientadresser med DNS sökningen (förvalt: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Avaktivera säkert läge. Åsidosätt en riktigt säkert läge händelse (förvalt: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Fel vid inläsning av plånboksfilen wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Tvångskör i säkert läge (förvalt: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Generera mynt (förvalt: %u)</translation> </message> @@ -3417,10 +3442,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ogiltig -proxy adress: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Begränsa signaturcachestorleken till <n> poster (förvalt: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Lyssna på JSON-RPC-anslutningar på <port> (förval: %u eller testnet: %u)</translation> </message> @@ -3433,6 +3454,10 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ha som mest <n> anslutningar till andra klienter (förvalt: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Gör så att plånboken sänder ut transaktionerna</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Maximal mottagningsbuffert per anslutning, <n>*1000 byte (förvalt: %u)</translation> </message> @@ -3441,10 +3466,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Maximal sändningsbuffert per anslutning, <n>*1000 byte (förvalt: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Acceptera bara blockkedjans matchande inbyggda kontrollpunkter (förvalt: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Skriv ut tidsstämpel i avlusningsinformationen (förvalt: %u)</translation> </message> @@ -3457,10 +3478,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Reläa icke P2SH multisig (förvalt: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Kör en tråd för att tömma plånboken periodiskt (förvalt: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Serverns certifikatfil (förvalt: %s)</translation> </message> @@ -3481,10 +3498,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ange antalet trådar för att hantera RPC anrop (förvalt: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Sätt DB_PRIVATE flaggan i plånbokens databasmiljö (förvalt: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Ange konfigurationsfil (förvalt: %s)</translation> </message> @@ -3501,10 +3514,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Spendera okonfirmerad växel när transaktioner sänds (förvalt: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Sluta köra efter importen av block från disk är klar (förvalt: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Tröskelvärde för att koppla ifrån klienter som missköter sig (förvalt: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_th_TH.ts b/src/qt/locale/bitcoin_th_TH.ts index 9535ac6a01..0980502968 100644 --- a/src/qt/locale/bitcoin_th_TH.ts +++ b/src/qt/locale/bitcoin_th_TH.ts @@ -1,4 +1,4 @@ -<TS language="th_TH" version="2.1"> +<TS language="th_TH" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -72,10 +72,6 @@ <translation>เปลี่ยนรหัสผ่าน</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>กรอกรหัสผ่านเก่าและรหัสผ่านใหม่สำหรับกระเป๋าสตางค์</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>ยืนยันการเข้ารหัสกระเป๋าสตางค์</translation> </message> @@ -345,8 +341,8 @@ <context> <name>TransactionTableModel</name> <message> - <source>Address</source> - <translation>ที่อยู่</translation> + <source>Label</source> + <translation>ชื่อ</translation> </message> </context> <context> diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index dc5762bc05..dcc82e644d 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -1,9 +1,9 @@ -<TS language="tr" version="2.1"> +<TS language="tr" version="2.0"> <context> <name>AddressBookPage</name> <message> <source>Right-click to edit address or label</source> - <translation>Adresi ya da etiketi düzenlemek için sağ düğme ile tıklayınız.</translation> + <translation>Adres veya etiketi düzenlemek için sağ tıklayınız.</translation> </message> <message> <source>Create a new address</source> @@ -15,7 +15,7 @@ </message> <message> <source>Copy the currently selected address to the system clipboard</source> - <translation>Şu anda seçili olan adresi sistem panosuna kopyala</translation> + <translation>Seçili adresi panoya kopyala</translation> </message> <message> <source>&Copy</source> @@ -35,7 +35,7 @@ </message> <message> <source>Export the data in the current tab to a file</source> - <translation>Güncel sekmedeki verileri bir dosyaya aktar</translation> + <translation>Açık olan sekmedeki verileri bir dosyaya aktar</translation> </message> <message> <source>&Export</source> @@ -67,11 +67,11 @@ </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>Bunlar ödeme yapmak için kullanacağınız Bitcoin adreslerinizdir. Bitcoin yollamadan önce meblağı ve alıcı adresini daima kontrol ediniz.</translation> + <translation>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.</translation> </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> - <translation>Bunlar ödeme almak için kullanacağınız Bitcoin adreslerinizdir. Her muamele için yeni bir alım adresi kullanmanız tavsiye edilir.</translation> + <translation>Bunlar ödemeleri almak için kullanacağınız Bitcoin adreslerinizdir. Her işlem için yeni bir alım adresi kullanmanız tavsiye edilir.</translation> </message> <message> <source>Copy &Label</source> @@ -110,7 +110,7 @@ </message> <message> <source>(no label)</source> - <translation>(boş etiket)</translation> + <translation>(etiket yok)</translation> </message> </context> <context> @@ -145,23 +145,19 @@ </message> <message> <source>This operation needs your wallet passphrase to decrypt the wallet.</source> - <translation>Bu işlem, cüzdan şifresini açmak için cüzdan parolasını gerektirir.</translation> + <translation>Bu işlem cüzdanın şifrelemesini açmak için cüzdan parolasını gerektirir.</translation> </message> <message> <source>Decrypt wallet</source> - <translation>Cüzdan şifresini aç</translation> + <translation>Cüzdanın şifrelemesini aç</translation> </message> <message> <source>Change passphrase</source> <translation>Parolayı değiştir</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Cüzdan için eski ve yeni parolaları giriniz.</translation> - </message> - <message> <source>Confirm wallet encryption</source> - <translation>Cüzdan şifrelenmesini teyit eder</translation> + <translation>Cüzdanın şifrelemesini teyit eder</translation> </message> <message> <source>Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!</source> @@ -172,6 +168,10 @@ <translation>Cüzdanınızı şifrelemek istediğinizden emin misiniz?</translation> </message> <message> + <source>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.</source> + <translation>Ş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.</translation> + </message> + <message> <source>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.</source> <translation>Ö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.</translation> </message> @@ -188,8 +188,8 @@ <translation>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.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Şifreleme işlemini tamamlamak için Bitcoin ş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.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Cüzdan için eski parolayı ve yeni parolayı giriniz.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>Bir Bitcoin adresine Bitcoin yolla</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Bitcoin seçeneklerinin yapılandırmasını değiştir</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Cüzdanı diğer bir konumda yedekle</translation> </message> @@ -403,6 +399,10 @@ <translation>Bitcoin Çekirdeği &hakkında</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Bitcoin Çekirdeği yapılandırma seçeneklerini değiştir</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Kullanılmış gönderme adresleri ve etiketlerin listesini göster</translation> </message> @@ -431,6 +431,10 @@ <translation>Hiçbir blok kaynağı mevcut değil...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Muamele tarihçesinden %n blok işlendi.</numerusform><numerusform>Muamele tarihçesinden %n blok işlendi</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n saat</numerusform><numerusform>%n saat</numerusform></translation> </message> @@ -478,35 +482,49 @@ <source>Up to date</source> <translation>Güncel</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>Muamele tarihçesinden %n blok işlendi</numerusform><numerusform>Muamele tarihçesinden %n blok işlendi</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Aralık kapatılıyor...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Muamele yollandı</translation> + <source>Date: %1 +</source> + <translation>Tarih: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Gelen muamele</translation> + <source>Amount: %1 +</source> + <translation>Meblağ: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Tarih: %1 -Meblağ: %2 -Tür: %3 -Adres: %4 + <translation>Tür: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Etiket: %1 </translation> </message> <message> + <source>Address: %1 +</source> + <translation>Adres: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Muamele yollandı</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Gelen muamele</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Cüzdan <b>şifrelenmiştir</b> ve şu anda <b>kilidi açıktır</b></translation> </message> @@ -697,6 +715,18 @@ Adres: %4 <translation>boş</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Eğer muamele boyutu 1000 bayttan yüksek ise bu etiket kırmızı hale gelir.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Eğer öncelik "ortadan" düşükse bu etiket kırmızı olur.</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Eğer herhangi bir alıcı %1'den düşük bir meblağ alırsa bu etiket kırmızı olur.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Giriş başına +/- %1 satoshi olarak değişebilir.</translation> </message> @@ -709,10 +739,6 @@ Adres: %4 <translation>hayır</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Eğer muamele boyutu 1000 bayttan büyükse bu etkiket kırmızı olur.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Bu, kB başına en az %1 ücret gerektiği anlamnına gelir.</translation> </message> @@ -725,14 +751,6 @@ Adres: %4 <translation>Yüksek öncelikli muamelelerin bir bloğa dahil olmaları daha olasıdır.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Eğer öncelik "ortadan" düşükse bu etiket kırmızı olur.</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Eğer herhangi bir alıcı %1'den düşük bir meblağ alırsa bu etiket kırmızı olur.</translation> - </message> - <message> <source>(no label)</source> <translation>(boş etiket)</translation> </message> @@ -853,30 +871,6 @@ Adres: %4 <source>command-line options</source> <translation>komut satırı seçenekleri</translation> </message> - <message> - <source>UI options</source> - <translation>Kullanıcı arayüzü seçenekleri</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Lisan belirt, mesela "de_De" (varsayılan: sistem dili)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Küçültülmüş olarak başlat</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Ödeme talebi için SSL kök sertifikalarını belirle (varsayılan: -system-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Başlatıldığında başlangıç ekranını göster (varsayılan: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Başlangıçta veri klasörü seç (varsayılan: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -959,14 +953,6 @@ Adres: %4 <translation>&Esas ayarlar</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Sistemde oturum açıldığında Bitcoin'i otomatik olarak başlat.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>Bitcoin'i sistem oturumuyla &başlat</translation> - </message> - <message> <source>Size of &database cache</source> <translation>&Veritabanı tamponunun boyutu</translation> </message> @@ -991,6 +977,14 @@ Adres: %4 <translation>Vekil sunucusunun IP adresi (mesela IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>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.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Kullanıcı arayüzünün dili burada belirtilebilir. Bu ayar Bitcoin Çekirdeği tekrar başlatıldığında etkinleşecektir.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>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.</translation> </message> @@ -1015,6 +1009,14 @@ Adres: %4 <translation>&Şebeke</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Sistemde oturum açıldığında Bitcoin Çekirdeğini otomatik olarak başlat.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>Bitcoin Çekirdeğini sistem oturumuyla &başlat</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = otomatik, <0 = bu kadar çekirdeği kullanma)</translation> </message> @@ -1079,10 +1081,6 @@ Adres: %4 <translation>İşlem çubuğu yerine sistem çekmecesine &küçült</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>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.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>Kapatma sırasında k&üçült</translation> </message> @@ -1095,10 +1093,6 @@ Adres: %4 <translation>Kullanıcı arayüzü &lisanı:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Kullanıcı arayüzünün dili burada belirtilebilir. Bu ayar Bitcoin tekrar başlatıldığında etkinleşecektir.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>Meblağları göstermek için &birim:</translation> </message> @@ -1135,8 +1129,8 @@ Adres: %4 <translation>Değişikliklerin uygulanması için istemcinin yeniden başlatılması lazımdır.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>İstemci kapanacaktır, devam etmek istiyor musunuz?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>İstemci kapanacaktır. Devam etmek istiyor musunuz?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1221,10 +1215,6 @@ Adres: %4 <source>Current total balance in watch-only addresses</source> <translation>Sadece izlenen adreslerdeki güncel toplam bakiye</translation> </message> - <message> - <source>out of sync</source> - <translation>eşleşme dışı</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1245,10 +1235,6 @@ Adres: %4 <translation>Ödeme talebi şebekesi istemci şebekesine denk gelmiyor.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Ödeme talebinin ömrü doldu.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Ödeme talebi başlatılmamış.</translation> </message> @@ -1281,14 +1267,26 @@ Adres: %4 <translation>Ödeme talebi okunamaz ya da işlenemez! Bunun sebebi geçersiz bir ödeme talebi dosyası olabilir.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Ödeme talebinin ömrü doldu.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Özel ödeme betiklerine teyit edilmemiş ödeme talepleri desteklenmez.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Geçersiz ödeme talebi.</translation> + </message> + <message> <source>Refund from %1</source> <translation>%1 öğesinden iade</translation> </message> <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>%1 ödeme talebi çok büyük (%2 bayt, müsaade edilen %3 bayt).</translation> + </message> + <message> <source>Payment request DoS protection</source> <translation>Ödeme talebi DoS koruması</translation> </message> @@ -1320,12 +1318,12 @@ Adres: %4 <translation>Kullanıcı Yazılımı</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Adres/Makine ismi</translation> + <source>Node/Service</source> + <translation>Düğüm/Servis</translation> </message> <message> <source>Ping Time</source> - <translation>Ping Zamanı</translation> + <translation>Ping Süresi</translation> </message> </context> <context> @@ -1355,14 +1353,6 @@ Adres: %4 <translation>%1 s</translation> </message> <message> - <source>NETWORK</source> - <translation>ŞEBEKE</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>BİLİNMİYOR</translation> - </message> - <message> <source>None</source> <translation>Boş</translation> </message> @@ -1453,6 +1443,10 @@ Adres: %4 <translation>Güncel blok sayısı</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>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.</translation> + </message> + <message> <source>Received</source> <translation>Alınan</translation> </message> @@ -1498,7 +1492,7 @@ Adres: %4 </message> <message> <source>Connection Time</source> - <translation>Bağlantı Zamanı</translation> + <translation>Bağlantı Süresi</translation> </message> <message> <source>Last Send</source> @@ -1518,7 +1512,11 @@ Adres: %4 </message> <message> <source>Ping Time</source> - <translation>Ping Zamanı</translation> + <translation>Ping Süresi</translation> + </message> + <message> + <source>Time Offset</source> + <translation>Saat Farkı</translation> </message> <message> <source>Last block time</source> @@ -1561,16 +1559,12 @@ Adres: %4 <translation>Hata ayıklama kütük dosyası</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Güncel veri klasöründen Bitcoin hata ayıklama kütük dosyasını açar. Büyük kütük dosyaları için bu birkaç saniye alabilir.</translation> - </message> - <message> <source>Clear console</source> <translation>Konsolu temizle</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Bitcoin RPC konsoluna hoş geldiniz.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Bitcoin Çekirdeği RPC konsoluna hoş geldiniz.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1861,14 +1855,6 @@ Adres: %4 <translation>ücret-ayarlarını-küçült</translation> </message> <message> - <source>Minimize</source> - <translation>Küçült</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Eğer özel ücret 1000 satoşi olarak ayarlandıysa ve muamele sadece 250 baytsa, "kilobayt başı" ücret olarak sadece 250 satoşi öder ve "asgari" 1000 satoşi öder. Bir kilobayttan yüksek muameleler için ikisi de kilobayt başı ödeme yapar.</translation> - </message> - <message> <source>per kilobyte</source> <translation>kilobayt başı</translation> </message> @@ -1877,6 +1863,10 @@ Adres: %4 <translation>Eğer özel ücret 1000 satoşi olarak ayarlandıysa ve muamele sadece 250 baytsa, "kilobayt başı" ücret olarak sadece 250 satoşi öder ve "toplam asgari" 1000 satoşi öder. Bir kilobayttan yüksek muameleler için ikisi de kilobayt başı ödeme yapar.</translation> </message> <message> + <source>Hide</source> + <translation>Sakla</translation> + </message> + <message> <source>total at least</source> <translation>toplam asgari</translation> </message> @@ -1997,10 +1987,6 @@ Adres: %4 <translation>veya</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Alıcı adresi geçerli değildir, lütfen denetleyiniz.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Ödeyeceğiniz tutarın sıfırdan yüksek olması gerekir.</translation> </message> @@ -2013,10 +1999,6 @@ Adres: %4 <translation>Toplam, %1 muamele ücreti ilâve edildiğinde bakiyenizi geçmektedir.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Çift adres bulundu, belli bir gönderi sırasında her adrese sadece tek bir gönderide bulunulabilir.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Muamelenin oluşturulması başarısız oldu!</translation> </message> @@ -2025,16 +2007,24 @@ Adres: %4 <translation>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.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> - <translation>%1 tutarından yüksek ücret delicesine aşırı yüksek bir ücret olarak kabul edilir.</translation> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>%1 tutarından yüksek ücret saçma derecede yüksek bir ücret olarak kabul edilir.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Ödeme talebinin ömrü doldu.</translation> </message> <message> <source>Pay only the minimum fee of %1</source> <translation>Sadece asgari ücret olan %1 tutarını öde</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Tahmini olarak %1 blok içinde teyide başlanacaktır.</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Alıcı adresi geçerli değildir. Lütfen denetleyiniz.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Çift adres bulundu: adresler herbiri için sadece bir kez kullanılmalıdır.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2108,12 +2098,24 @@ Adres: %4 <translation>Bu unsuru kaldır</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>Ücret yollanan meblağdan alınacaktır. Alıcı meblağ alanında girdiğinizden daha az bitcoin alacaktır. Eğer birden çok alıcı seçiliyse ücret eşit olarak bölünecektir.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>Ücreti meblağdan düş</translation> + </message> + <message> <source>Message:</source> <translation>Mesaj:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Bu, teyit edilmiş bir ödeme talebidir.</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Bu, kimliği doğrulanmamış bir ödeme talebidir.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Bu, kimliği doğrulanmış bir ödeme talebidir.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2124,10 +2126,6 @@ Adres: %4 <translation>Bitcoin: URI'siyle ilişkili ve bilginiz için muameleyle saklanacak bir mesaj. Not: Bu mesaj Bitcoin şebekesi üzerinden gönderilmeyecektir.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Bu, teyit edilmemiş bir ödeme talebidir.</translation> - </message> - <message> <source>Pay To:</source> <translation>Şu adrese öde:</translation> </message> @@ -2158,8 +2156,8 @@ Adres: %4 <translation>Mesaj &imzala</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Bir adresin sizin olduğunu ispatlamak için adresinizle mesaj imzalayabilirsiniz. Oltalama saldırılarının kimliğinizi imzanızla elde etmeyi deneyebilecekleri için belirsiz hiçbir şey imzalamamaya dikkat ediniz. Sadece ayrıntılı açıklaması olan ve tümüne katıldığınız ifadeleri imzalayınız.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Adreslerinize yollanan bitcoinleri alabileceğiniz ispatlamak için adreslerinizle mesaj/anlaşma imzalayabilirsiniz. Oltalama saldırılarının kimliğinizi imzanızla elde etmeyi deneyebilecekleri için belirsiz ya da rastgele hiçbir şey imzalamamaya dikkat ediniz. Sadece ayrıntılı açıklaması olan ve tümüne katıldığınız ifadeleri imzalayınız.</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2214,8 +2212,8 @@ Adres: %4 <translation>Mesaj &kontrol et</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>İmza için kullanılan adresi, mesajı (satır sonları, boşluklar, sekmeler vs. karakterleri tam olarak kopyaladığınızdan emin olunuz) ve imzayı aşağıda giriniz. Bir ortadaki adam saldırısı tarafından kandırılmaya mâni olmak için imzadan, imzalı mesajın içeriğini aşan bir anlam çıkarmamaya dikkat ediniz.</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Alıcının adresini, mesajı (satır sonları, boşluklar, sekmeler vs. karakterleri tam olarak kopyaladığınızdan emin olunuz) ve imzayı aşağıda giriniz. Bir ortadaki adam saldırısı tarafından kandırılmaya mâni olmak için imzadan, imzalı mesajın içeriğini aşan bir anlam çıkarmamaya dikkat ediniz. Bunun sadece imzalayan tarafın adres ile alım yapabildiğini ispatladığını ve herhangi bir muamelenin gönderi tarafını kanıtlayamayacağını unutmayınız!</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2481,10 +2479,6 @@ Adres: %4 <translation>Tür</translation> </message> <message> - <source>Address</source> - <translation>Adres</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Olgunlaşmamış (%1 teyit, %2 teyit ardından kullanılabilir olacaktır)</translation> </message> @@ -2513,6 +2507,10 @@ Adres: %4 <translation>Çevrim dışı</translation> </message> <message> + <source>Label</source> + <translation>Etiket</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Teyit edilmemiş</translation> </message> @@ -2569,8 +2567,8 @@ Adres: %4 <translation>Bu muamelede sadece izlenen bir adresin bulunup bulunmadığı.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Muamelenin alıcı adresi.</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Muamelenin kullanıcı tanımlı niyeti/amacı.</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2823,16 +2821,16 @@ Adres: %4 <translation>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.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Blokların anında çözülebileceği özel bir zincir kullanan regresyon deneme kipine gir.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Bir cüzdan muamelesi değiştiğinde komutu çalıştır (komuttaki %s muamele kimliği ile değiştirilecektir)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>Bu kipte -genproclimit kaç sayıda bloğun anında oluşturulduğunu kontrol eder.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Tek cüzdan muamelesinde kullanılacak azami toplam ücret; bunu çok düşük olarak ayarlamak büyük muameleleri iptal edebilir (varsayılan: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Depolama gerekliliğini eski blokları silerek düşür. Bu kip cüzdan desteğini devre dışı bırakır ve -txindex ile uyumsuzdur. İkaz: Bu ayarı geri almak tüm blok zincirini yeniden indirmeyi gerektirir. (varsayılan: 0 = blokları silmeyi devre dışı bırak, >%u = MB olarak blok dosyaları için kullanılacak hedef boyut)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2847,6 +2845,14 @@ Adres: %4 <translation>Bu bilgisayarda %s unsuruna bağlanılamadı. Bitcoin Çekirdeği muhtemelen hâlihazırda çalışmaktadır.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>İKAZ: anormal yüksek sayıda blok oluşturulmuştur, %d blok son %d saat içinde alınmıştır (%d bekleniyordu)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>İKAZ: ağ bağlantınızı kontrol ediniz, %d blok son %d saat içinde alınmıştır (%d bekleniyordu)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Uyarı: -paytxfee çok yüksek bir değere ayarlanmış! Bu, muamele gönderirseniz ödeyeceğiniz muamele ücretidir.</translation> </message> @@ -2903,10 +2909,6 @@ Adres: %4 <translation>Hata ayıklama/deneme seçenekleri:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Kendi IP adresini keşfet (varsayılan: dinlenildiğinde ve -externalip yoksa 1)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Cüzdanı yükleme ve cüzdan RPC çağrılarını devre dışı bırak</translation> </message> @@ -2967,8 +2969,12 @@ Adres: %4 <translation>Sadece <net> şebekesindeki düğümlere bağlan (ipv4, ipv6 veya onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Blok zinciri indeksini güncel blk000??.dat dosyalarından tekrar inşa et</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>Prune negatif bir değerle yapılandırılamaz.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Prune kipi -txindex ile uyumsuzdur.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2983,10 +2989,6 @@ Adres: %4 <translation>Cüzdan dosyası belirtiniz (veri klasörünün içinde)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Bu, regresyon deneme araçları ve uygulama geliştirmesi için tasarlanmıştır. </translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Dinleme portunu haritalamak için UPnP kullan (varsayılan: %u)</translation> </message> @@ -3007,6 +3009,10 @@ Adres: %4 <translation>Cüzdan seçenekleri:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Uyarı: Bu sürüm çok eskidir; güncellemeniz gerekir!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>-txindex'i değiştirmek için veritabanını -reindex kullanarak tekrar inşa etmeniz gerekmektedir</translation> </message> @@ -3035,14 +3041,14 @@ Adres: %4 <translation>%s veri dizininde kilit elde edilemedi. Bitcoin Çekirdeği muhtemelen hâlihazırda çalışmaktadır.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Devamlı olarak ücretsiz muameleleri dakikada <n>*1000 bayt olarak sınırla (varsayılan: %u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>Yeni dosyaları umask 077 yerine varsayılan izinlerle oluştur (sadece devre dışı cüzdan işlevselliği ile etkilidir)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Kendi IP adreslerini keşfet (varsayılan: dinlenildiğinde ve -externalip ya da -proxy yoksa 1)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Hata: İçeri gelen bağlantıların dinlenmesi başarısız oldu (dinleme %s hatasını verdi)</translation> </message> @@ -3059,10 +3065,6 @@ Adres: %4 <translation>Kb başına BTC olarak bundan düşük ücretler aktarım için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Kb başına BTC olarak bundan düşük ücretler muamele oluşturulması için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Eğer paytxfee ayarlanmadıysa kafi derecede ücret ekleyin ki muameleler teyite vasati n blok içinde başlasın (varsayılan: %u)</translation> </message> @@ -3075,14 +3077,18 @@ Adres: %4 <translation>Aktardığımız ve oluşturduğumuz veri taşıyıcı muamelelerindeki azami veri boyutu (varsayılan: %u)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>Tek cüzdan muamelesinde kullanılacak azami toplam ücret, çok düşük ayarlamak büyük muameleleri iptal edebilir (varsayılan: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Prune, asgari değer olan %d MB'den düşük olarak ayarlanmıştır. Lütfen daha yüksek bir sayı kullanınız.</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Adres sayısı azaldıysa DNS sorgulamasıyla eş adresleri ara (varsayılan: 1 -connect kullanılmadıysa)</translation> </message> <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Her vekil bağlantısı için kimlik verilerini rastgele yap. Bu, Tor akış izolasyonunu etkinleştirir (varsayılan: %u)</translation> + </message> + <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Yüksek öncelikli/düşük ücretli muamelelerin azami boyutunu bayt olarak ayarla (varsayılan: %d)</translation> </message> @@ -3091,6 +3097,10 @@ Adres: %4 <translation>Etkinse bitcoin oluşuturulmasına atanan iş parçacığı sayısını ayarla (-1 = tüm çekirdekler, varsayılan: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Bu muamele, ücret düşüldükten sonra göndermek için çok düşük</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -3131,14 +3141,34 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>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</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Prune olmayan kipe dönmek için veritabanını -reindex ile tekrar derlemeniz gerekir. Bu, tüm blok zincirini tekrar indirecektir</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(varsayılan: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Herkese açık REST taleplerini kabul et (varsayılan: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>En iyi zincir etkinleştiriliyor...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Prune kipindeki bir cüzdan ile çalışamaz.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>-whitebind adresi çözümlenemedi: '%s'</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Başlangıçta veri klasörü seç (varsayılan: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>SOCKS5 vekil sunucusu vasıtasıyla bağlan</translation> </message> @@ -3155,6 +3185,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>wallet.dat dosyasının yüklenmesinde hata: Cüzdan Bitcoin Çekirdeğinin daha yeni bir sürümünü gerektirmektedir</translation> </message> <message> + <source>Error reading from database, shutting down.</source> + <translation>Veritabanından okumada hata, kapatılıyor.</translation> + </message> + <message> <source>Error: Unsupported argument -tor found, use -onion.</source> <translation>Hata: Deskteklenmeyen -tor argümanı bulundu, -onion kullanınız.</translation> </message> @@ -3211,12 +3245,16 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>RPC sunucu seçenekleri:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Her <n> şebeke mesajından rastgele 1 mesajı görmezden gel</translation> + <source>RPC support for HTTP persistent connections (default: %d)</source> + <translation>Kalıcı HTTP bağlantıları için RPC desteği (varsayılan: %d)</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Her <n> şebeke mesajından rastgele birini bulanıklaştır</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Başlangıçta blok zinciri indeksini güncel blk000??.dat dosyalarından tekrar inşa et</translation> + </message> + <message> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>P2P ağından gelen önemli uyarıları alın ve gösterin (önseçili değer: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3227,10 +3265,22 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Muameleleri mümkünse ücretsiz olarak gönder (varsayılan: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Ödeme talebi için SSL kök sertifikalarını belirle (varsayılan: -system-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Lisan belirt, mesela "de_De" (varsayılan: sistem dili)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Tüm hata ayıklama seçeneklerini göster (kullanımı: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Başlatıldığında başlangıç ekranını göster (varsayılan: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>İstemci başlatıldığında debug.log dosyasını küçült (varsayılan: -debug bulunmadığında 1)</translation> </message> @@ -3239,6 +3289,14 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Muamelenin imzalanması başarısız oldu</translation> </message> <message> + <source>Start minimized</source> + <translation>Küçültülmüş olarak başlat</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Muamele meblağı ücreti ödemek için çok düşük</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Bu, deneysel bir yazılımdır.</translation> </message> @@ -3259,6 +3317,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Muamele çok büyük</translation> </message> <message> + <source>UI Options:</source> + <translation>Arayüz Seçenkleri:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Bu bilgisayarda %s unsuruna bağlanılamadı (bağlanma %s hatasını verdi)</translation> </message> @@ -3279,10 +3341,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Uyarı</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Uyarı: Bu sürüm çok eskidir, güncellemeniz gerekir!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Uyarı: Deskteklenmeyen -benchmark argümanı görmezden gelindi, -debug=bench kullanınız.</translation> </message> @@ -3343,18 +3401,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = tx meta verilerini tut mesela hesap sahibi ve ödeme talebi bilgileri, 2 = tx meta verilerini at)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Veritabanı etkinliğini bellekten disk kütüğüne her <n> megabaytta aktar (varsayılan: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>-checkblocks'un blok kontrolünün ne kadar kapsamlı olacağı (0 ilâ 4, varsayılan: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Blok oluşturulduğunda muamele önceliğini ve kB başı ücreti kütüğe al (varsayılan: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Muamelelerin tamamının indeksini tut, getrawtransaction rpc çağrısı tarafından kullanılır (varsayılan: %u)</translation> </message> @@ -3383,18 +3433,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Eş adresleri sorgulaması için daima DNS aramasını kullan (varsayılan: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Güvenli kipi devre dışı bırak, gerçek bir güvenli olayı geçersiz kıl (varsayılan: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>wallet.dat dosyasının yüklenmesinde hata oluştu</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Güvenli kipi zorla (varsayılan: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Bitcoin oluştur (varsayılan: %u)</translation> </message> @@ -3411,10 +3453,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Geçersiz -proxy adresi: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>İmza arabelleğinin boyutunu <n> unsurla sınırla (varsayılan: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>JSON-RPC bağlantılarını <port> üzerinde dinle (varsayılan: %u veya tesnet: %u)</translation> </message> @@ -3427,6 +3465,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Eşler ile en çok <n> adet bağlantı kur (varsayılan: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Cüzdanın muameleleri yayınlamasını sağla</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Her bağlantı için azami alım tamponu, <n>*1000 bayt (varsayılan: %u)</translation> </message> @@ -3435,10 +3477,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Her bağlantı için azami yollama tamponu, <n>*1000 bayt (varsayılan: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Sadece yerleşik kontrol noktalarıyla eşleşen blok zincirini kabul et (varsayılan: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Hata ayıklama verilerinin önüne zaman damgası ekle (varsayılan: %u)</translation> </message> @@ -3451,10 +3489,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>P2SH olmayan çoklu imzaları aktar (varsayılan: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Periyodik olarak cüdanı diske yazdırmak için bir iş parçacığı çalıştır (varsayılan: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Sunucu sertifika dosyası (varsayılan: %s)</translation> </message> @@ -3475,10 +3509,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Hizmet RCP aramaları iş parçacığı sayısını belirle (varsayılan: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Cüzdan veritabanı ortamında DB_PRIVATE bayrağını koyar (varsayılan: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Yapılandırma dosyası belirtiniz (varsayılan: %s)</translation> </message> @@ -3495,10 +3525,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Gönderme muamelelerinde teyit edilmemiş para üstünü harca (varsayılan: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Diskten blokları içeri aktardıktan sonra çalışmayı durdur (varsayılan: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Aksaklık gösteren eşlerle bağlantıyı kesme sınırı (varsayılan: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index 809f8e2d24..21ab4ac191 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -1,9 +1,9 @@ -<TS language="uk" version="2.1"> +<TS language="uk" version="2.0"> <context> <name>AddressBookPage</name> <message> <source>Right-click to edit address or label</source> - <translation>Клік правою кнопкою для редагування адреси або мітки</translation> + <translation>Клікніть правою кнопкою для редагування адреси або мітки</translation> </message> <message> <source>Create a new address</source> @@ -71,7 +71,7 @@ </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> - <translation>Це ваша нова Bitcoin адреса для отримування платежів. Рекомендовано використовувати нову адресу для кожної транзакції.</translation> + <translation>Це ваша нова Bitcoin адреса для отримання платежів. Рекомендовано використовувати нову адресу для кожної транзакції.</translation> </message> <message> <source>Copy &Label</source> @@ -156,10 +156,6 @@ <translation>Змінити пароль</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Ввести старий та новий паролі для гаманця.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Підтвердити шифрування гаманця</translation> </message> @@ -172,8 +168,12 @@ <translation>Ви дійсно хочете зашифрувати свій гаманець?</translation> </message> <message> + <source>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.</source> + <translation>Клієнт «Bitcoin Core» буде закрито для завершення процесу шифрування. Пам'ятайте, що шифрування гаманця не зможе повністю захистити ваші біткоїни від крадіжки якщо ваш комп'ютер буде інфіковано шкідливими програмами.</translation> + </message> + <message> <source>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.</source> - <translation>ВАЖЛИВО: Всі попередні резервні копії, які ви зробили з вашого файлу гаманця повинні бути замінені новоствореним, зашифрованим файлом гаманця. З міркувань безпеки, попередні резервні копії незашифрованого файла гаманця стануть марними одразу ж, як тільки ви почнете використовувати новий, зашифрований гаманець.</translation> + <translation>ВАЖЛИВО: Всі попередні резервні копії, які ви зробили з вашого файлу гаманця повинні бути замінені новоствореним, зашифрованим файлом гаманця. З міркувань безпеки, попередні резервні копії незашифрованого файла гаманця стануть непридатними одразу ж, як тільки ви почнете використовувати новий, зашифрований гаманець.</translation> </message> <message> <source>Warning: The Caps Lock key is on!</source> @@ -185,11 +185,11 @@ </message> <message> <source>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>.</source> - <translation>Введіть нову кодову фразу для гаманця.<br/>Будь ласка, використовуйте кодові фрази що містять <b> як мінімум десять випадкових символів </b> або <b> як мінімум вісім слів </b>.</translation> + <translation>Введіть нову кодову фразу для гаманця.<br/>Будь ласка, використовуйте кодові фрази що містять <b> щонайменше десять випадкових символів </b> або <b> щонайменше вісім слів </b>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Біткоін-клієнт буде закрито для завершення процесу шифрування. Пам'ятайте, що шифрування гаманця не може повністю захистити ваші біткоіни від крадіжки, у випадку якщо ваш комп'ютер буде інфіковано шкідливими програмами.</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Введіть старий пароль та новий пароль до гаманця.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -240,11 +240,11 @@ </message> <message> <source>Show general overview of wallet</source> - <translation>Показати загальний огляд гаманця</translation> + <translation>Показати стан гаманця</translation> </message> <message> <source>&Transactions</source> - <translation>Транзакції</translation> + <translation>&Транзакції</translation> </message> <message> <source>Browse transaction history</source> @@ -311,10 +311,6 @@ <translation>Відправити монети на вказану адресу</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Редагувати параметри</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Резервне копіювання гаманця в інше місце</translation> </message> @@ -324,7 +320,7 @@ </message> <message> <source>&Debug window</source> - <translation>Вікно зневадження</translation> + <translation>В&ікно зневадження</translation> </message> <message> <source>Open debugging and diagnostic console</source> @@ -356,7 +352,7 @@ </message> <message> <source>&Show / Hide</source> - <translation>Показати / Приховати</translation> + <translation>Показа&ти / Приховати</translation> </message> <message> <source>Show or hide the main Window</source> @@ -364,7 +360,7 @@ </message> <message> <source>Encrypt the private keys that belong to your wallet</source> - <translation>Шифрування закритих ключів, які належать вашому гаманці</translation> + <translation>Зашифрувати закриті ключі, що знаходяться у вашому гаманці</translation> </message> <message> <source>Sign messages with your Bitcoin addresses to prove you own them</source> @@ -400,7 +396,11 @@ </message> <message> <source>&About Bitcoin Core</source> - <translation>&Про Bitcoin Core</translation> + <translation>П&ро Bitcoin Core</translation> + </message> + <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Редагувати параметри Bitcoin Core</translation> </message> <message> <source>Show the list of used sending addresses and labels</source> @@ -416,7 +416,7 @@ </message> <message> <source>&Command-line options</source> - <translation>Параметри командного рядка</translation> + <translation>П&араметри командного рядка</translation> </message> <message> <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> @@ -424,13 +424,17 @@ </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n активне з'єднання з мережею</numerusform><numerusform>%n активні з'єднання з мережею</numerusform><numerusform>%n активних з'єднань з мережею Bitcoin</numerusform></translation> + <translation><numerusform>%n активне з'єднання з мережею Bitcoin</numerusform><numerusform>%n активні з'єднання з мережею Bitcoin</numerusform><numerusform>%n активних з'єднань з мережею Bitcoin</numerusform></translation> </message> <message> <source>No block source available...</source> <translation>Недоступно жодного джерела блоків...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Оброблено %n блок історії транзакцій.</numerusform><numerusform>Оброблено %n блоки історії транзакцій.</numerusform><numerusform>Оброблено %n блоків історії транзакцій.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n година</numerusform><numerusform>%n години</numerusform><numerusform>%n годин</numerusform></translation> </message> @@ -452,7 +456,7 @@ </message> <message> <source>%1 behind</source> - <translation>%1 позаду</translation> + <translation>%1 тому</translation> </message> <message> <source>Last received block was generated %1 ago.</source> @@ -478,35 +482,49 @@ <source>Up to date</source> <translation>Синхронізовано</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>Оброблено %n блок історії транзакцій.</numerusform><numerusform>Оброблено %n блоки історії транзакцій.</numerusform><numerusform>Оброблено %n блоків історії транзакцій.</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>Синхронізується...</translation> </message> <message> - <source>Sent transaction</source> - <translation>Надіслані транзакції</translation> + <source>Date: %1 +</source> + <translation>Дата: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>Отримані транзакції</translation> + <source>Amount: %1 +</source> + <translation>Кількість: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>Дата: %1 -Кількість: %2 -Тип: %3 -Адреса: %4 + <translation>Тип: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Мітка: %1 </translation> </message> <message> + <source>Address: %1 +</source> + <translation>Адреса: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Надіслані транзакції</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Отримані транзакції</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation><b>Зашифрований</b> гаманець <b>розблоковано</b></translation> </message> @@ -538,7 +556,7 @@ Address: %4 </message> <message> <source>Amount:</source> - <translation>Кількість:</translation> + <translation>Сума:</translation> </message> <message> <source>Priority:</source> @@ -610,11 +628,11 @@ Address: %4 </message> <message> <source>Copy amount</source> - <translation>Копіювати кількість</translation> + <translation>Скопіювати суму</translation> </message> <message> <source>Copy transaction ID</source> - <translation>Копіювати ID транзакції </translation> + <translation>Скопіювати ID транзакції </translation> </message> <message> <source>Lock unspent</source> @@ -626,31 +644,31 @@ Address: %4 </message> <message> <source>Copy quantity</source> - <translation>Копіювати кількість</translation> + <translation>Скопіювати кількість</translation> </message> <message> <source>Copy fee</source> - <translation>Копіювати комісію</translation> + <translation>Скопіювати комісію</translation> </message> <message> <source>Copy after fee</source> - <translation>Копіювати після комісії</translation> + <translation>Скопіювати після комісії</translation> </message> <message> <source>Copy bytes</source> - <translation>Копіювати байти</translation> + <translation>Скопіювати байти</translation> </message> <message> <source>Copy priority</source> - <translation>Копіювати пріорітет</translation> + <translation>Скопіювати пріорітет</translation> </message> <message> <source>Copy dust</source> - <translation>Копіювати пил</translation> + <translation>Скопіювати пил</translation> </message> <message> <source>Copy change</source> - <translation>Копіювати решту</translation> + <translation>Скопіювати решту</translation> </message> <message> <source>highest</source> @@ -697,6 +715,18 @@ Address: %4 <translation>відсутній</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Ця позначка стане червоною, якщо розмір транзакції перевищить 1000 байтів.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Ця позначка стане червоною, якщо пріоритет транзакції менше, ніж «середній».</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Ця позначка стане червоною, якщо будь-який отримувач отримає суму, меншу за %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Може відрізнятися на +/- %1 сатоші за вхід</translation> </message> @@ -709,10 +739,6 @@ Address: %4 <translation>ні</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Ця позначка буде червоною, якщо розмір транзакції вищий за 1000 байт.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Це означає, що необхідно внести комісію (щонайменше %1 за КБ).</translation> </message> @@ -725,14 +751,6 @@ Address: %4 <translation>Транзакції з вищим пріоритетом мають більше шансів бути включеними до блоку.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Ця позначка буде червоною, якщо пріоритет транзакції нижчий за «середній».</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Ця позначка буде червоною, якщо будь хто з отримувачів отримає менше ніж %1.</translation> - </message> - <message> <source>(no label)</source> <translation>(немає назви)</translation> </message> @@ -804,7 +822,7 @@ Address: %4 <name>FreespaceChecker</name> <message> <source>A new data directory will be created.</source> - <translation>Буде створена новий каталог даних.</translation> + <translation>Буде створено новий каталог даних.</translation> </message> <message> <source>name</source> @@ -853,30 +871,6 @@ Address: %4 <source>command-line options</source> <translation>параметри командного рядка</translation> </message> - <message> - <source>UI options</source> - <translation>Параметри інтерфейсу</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Встановлення мови, наприклад "de_DE" (типово: системна)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Запускати згорнутим</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Вказати кореневі SSL-сертифікати для запиту платежу (типово: -системні-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Показувати заставку під час запуску (типово: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Обрати каталог даних під час запуску (типово: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -959,14 +953,6 @@ Address: %4 <translation>&Головні</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Автоматично запускати гаманець при вході до системи.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>&Запускати гаманець при вході в систему</translation> - </message> - <message> <source>Size of &database cache</source> <translation>Розмір &кешу бази даних</translation> </message> @@ -976,7 +962,7 @@ Address: %4 </message> <message> <source>Number of script &verification threads</source> - <translation>Кількість потоків сценарію перевірки</translation> + <translation>Кількість потоків &сценарію перевірки</translation> </message> <message> <source>Accept connections from outside</source> @@ -991,6 +977,14 @@ Address: %4 <translation>IP-адреса проксі-сервера (наприклад IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Згортати замість закриття. Якщо ця опція включена, програма закриється лише після вибору відповідного пункту в меню.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Встановлює мову інтерфейсу. Зміни набудуть чинності після перезапуску Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>Сторонні URL (наприклад, block explorer), що з'являться на вкладці транзакцій у вигляді пункту контекстного меню. %s в URL буде замінено на хеш транзакції. Для відокремлення URLів використовуйте вертикальну риску |.</translation> </message> @@ -1008,13 +1002,21 @@ Address: %4 </message> <message> <source>&Reset Options</source> - <translation>Скинути параметри</translation> + <translation>С&кинути параметри</translation> </message> <message> <source>&Network</source> <translation>&Мережа</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Автоматично запускати Bitcoin Core при вході до системи.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Запускати Bitcoin Core при вході до системи</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = автоматично, <0 = вказує кількість вільних ядер)</translation> </message> @@ -1079,10 +1081,6 @@ Address: %4 <translation>Мінімізувати &у трей</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>Згортати замість закриття. Якщо ця опція включена, програма закриється лише після вибору відповідного пункту в меню.</translation> - </message> - <message> <source>M&inimize on close</source> <translation>Згортати замість закритт&я</translation> </message> @@ -1095,10 +1093,6 @@ Address: %4 <translation>Мов&а інтерфейсу користувача:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Встановлює мову інтерфейсу. Зміни набудуть чинності після перезапуску Bitcoin.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>В&имірювати монети в:</translation> </message> @@ -1135,8 +1129,8 @@ Address: %4 <translation>Для застосування змін необхідно перезапустити клієнта.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Клієнт вимкнеться, продовжувати?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Клієнт буде вимкнено. Продовжити?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1207,7 +1201,7 @@ Address: %4 </message> <message> <source>Recent transactions</source> - <translation>Недавні транзакції</translation> + <translation>Останні транзакції</translation> </message> <message> <source>Unconfirmed transactions to watch-only addresses</source> @@ -1221,10 +1215,6 @@ Address: %4 <source>Current total balance in watch-only addresses</source> <translation>Поточний сукупний баланс в адресах для спостереження</translation> </message> - <message> - <source>out of sync</source> - <translation>не синхронізовано</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1245,10 +1235,6 @@ Address: %4 <translation>Мережа запиту платежу не є мережею клієнта.</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>Запит платежу прострочено.</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>Запит платежу не ініціалізовано.</translation> </message> @@ -1281,14 +1267,26 @@ Address: %4 <translation>Неможливо прочитати файл запиту платежу! Ймовірно, файл пошкоджено.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Запит платежу прострочено.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Неперевірені запити платежів з власними платіжними сценаріями не підтримуються.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Помилка в запиті платежу.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Відшкодування з %1</translation> </message> <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>Запит платежу %1 занадто великий (%2 байт, дозволено %3 байт).</translation> + </message> + <message> <source>Payment request DoS protection</source> <translation>Оплата потребує захисту DoS</translation> </message> @@ -1320,8 +1318,8 @@ Address: %4 <translation>Клієнт користувача</translation> </message> <message> - <source>Address/Hostname</source> - <translation>Адреса/Ім'я хоста</translation> + <source>Node/Service</source> + <translation>Вузол/Сервіс</translation> </message> <message> <source>Ping Time</source> @@ -1355,14 +1353,6 @@ Address: %4 <translation>%1 с</translation> </message> <message> - <source>NETWORK</source> - <translation>МЕРЕЖА</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>НЕВІДОМО</translation> - </message> - <message> <source>None</source> <translation>Відсутні</translation> </message> @@ -1453,6 +1443,10 @@ Address: %4 <translation>Поточне число блоків</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Відкрити файл журналу налагодження Bitcoin Core з поточного каталогу даних. Це може зайняти кілька секунд для великих файлів журналів.</translation> + </message> + <message> <source>Received</source> <translation>Отримано</translation> </message> @@ -1521,16 +1515,20 @@ Address: %4 <translation>Затримка</translation> </message> <message> + <source>Time Offset</source> + <translation>Різниця часу</translation> + </message> + <message> <source>Last block time</source> <translation>Час останнього блоку</translation> </message> <message> <source>&Open</source> - <translation>Відкрити</translation> + <translation>&Відкрити</translation> </message> <message> <source>&Console</source> - <translation>Консоль</translation> + <translation>&Консоль</translation> </message> <message> <source>&Network Traffic</source> @@ -1561,16 +1559,12 @@ Address: %4 <translation>Файл звіту зневадження</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Відкрийте файл журналу налагодження Bitcoin з поточного каталогу даних. Це може зайняти кілька секунд для великих файлів журналів.</translation> - </message> - <message> <source>Clear console</source> <translation>Очистити консоль</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Вітаємо у консолі Bitcoin RPC.</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Вітаємо у RPC-консолі Bitcoin Core.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1712,11 +1706,11 @@ Address: %4 </message> <message> <source>Copy &URI</source> - <translation>Скопіювати URI</translation> + <translation>&Скопіювати URI</translation> </message> <message> <source>Copy &Address</source> - <translation>Скопіювати адресу</translation> + <translation>Скопіювати &адресу</translation> </message> <message> <source>&Save Image...</source> @@ -1861,20 +1855,16 @@ Address: %4 <translation>згорнути налаштування оплат</translation> </message> <message> - <source>Minimize</source> - <translation>Мінімізувати</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Якщо оплата користувача встановлюється в 1000 Satoshi і розмір передачі всього 250 байт, то "за кілобайт" платить тільки 250 Satoshi, в той час як "щонайменше" платить 1000 satoshis. Для передач більших, ніж кілобайт обоє платять за кілобайт.</translation> - </message> - <message> <source>per kilobyte</source> <translation>за кілобайт</translation> </message> <message> <source>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.</source> - <translation>Якщо оплата користувача встановлюється в 1000 Satoshi і розмір передачі всього 250 байт, то "за кілобайт" платить тільки 250 Satoshi, в той час як "всього щонайменше" платить 1000 satoshis. Для передач більших, ніж кілобайт обоє платять за кілобайт.</translation> + <translation>Якщо комісія встановлюється в 1000 сатоші і розмір транзакції лише 250 байтів, то опція "за кілобайт" встановлює комісію в 250 сатоші, в той час, як "всього щонайменше" - в 1000 сатоші. Для транзакцій більших за кілобайт в обох випадках буде знято комісію за кілобайт.</translation> + </message> + <message> + <source>Hide</source> + <translation>Приховати</translation> </message> <message> <source>total at least</source> @@ -1882,7 +1872,7 @@ Address: %4 </message> <message> <source>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.</source> - <translation>Оплата тільки мінімальних зборів є прийнятною до тих пір, як обсяг транзакцій там є меншим аніж простору в блоках. Але майте на увазі, що це може анулювати транзакцію, якщо попит на Bitcoin транзакції стане значно більшим, ніж мережа зможе обробити.</translation> + <translation>Оплата тільки мінімальної комісії є прийнятною, допоки обсяг транзакцій є меншим простору в блоках. Але майте на увазі, що це може анулювати транзакцію, якщо попит на Bitcoin транзакції стане більшим, ніж мережа зможе обробити.</translation> </message> <message> <source>(read the tooltip)</source> @@ -1898,7 +1888,7 @@ Address: %4 </message> <message> <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> - <translation>(Розумна оплата ще не ініціалізована. Це звичайно займає кілька блоків...)</translation> + <translation>(Розумну оплату ще не ініціалізовано. Це, зазвичай, триває кілька блоків...)</translation> </message> <message> <source>Confirmation time:</source> @@ -1966,7 +1956,7 @@ Address: %4 </message> <message> <source>Copy amount</source> - <translation>Копіювати кількість</translation> + <translation>Копіювати суму</translation> </message> <message> <source>Copy fee</source> @@ -1997,10 +1987,6 @@ Address: %4 <translation>або</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>Адреса отримувача невірна, будь ласка перепровірте.</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>Кількість монет для відправлення повинна бути більше 0.</translation> </message> @@ -2013,10 +1999,6 @@ Address: %4 <translation>Сума перевищить ваш баланс, якщо комісія %1 буде додана до вашої транзакції.</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>Знайдено адресу що дублюється. Відправлення на кожну адресу дозволяється лише один раз на кожну операцію переказу.</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>Не вдалося створити транзакцію!</translation> </message> @@ -2025,16 +2007,28 @@ Address: %4 <translation>Транзакцію відхилено! Це може статись, якщо декілька монет з вашого гаманця вже використані, наприклад, якщо ви використовуєте одну копію гаманця (wallet.dat), а монети були використані з іншої копії, але не позначені як використані в цій.</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> + <source>A fee higher than %1 is considered an absurdly high fee.</source> <translation>Плата вища, ніж %1 вважається шалено високою.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Запит платежу прострочено.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Перше підтвердження очікується протягом %n блоку.</numerusform><numerusform>Перше підтвердження очікується протягом %n блоків.</numerusform><numerusform>Перше підтвердження очікується протягом %n блоків.</numerusform></translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> - <translation>Платити тільки мінімальний збір у розмірі %1</translation> + <translation>Платити тільки мінімальну комісію у розмірі %1</translation> + </message> + <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Адреса отримувача неправильна. Будь ласка, перевірте її.</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>Розрахунковий початок підтвердження протягом %1 блоку(ів).</translation> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Знайдено адресу, що дублюється: кожна адреса має бути вказана не більше одного разу.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2108,12 +2102,24 @@ Address: %4 <translation>Видалити цей запис</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>Комісію буде знято зі вказаної суми. До отримувача надійде менше біткоінів, ніж було вказано в полі кількості. Якщо ж отримувачів декілька - комісію буде розподілено між ними.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>В&ідняти комісію від суми</translation> + </message> + <message> <source>Message:</source> <translation>Повідомлення:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>Це перевірений запит платежу.</translation> + <source>This is an unauthenticated payment request.</source> + <translation>Цей запит платежу не є автентифікованим.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Цей запит платежу є автентифікованим.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2124,10 +2130,6 @@ Address: %4 <translation>Повідомлення, що було додане до bitcoin:URI та буде збережено разом з транзакцією для довідки. Примітка: Це повідомлення не буде відправлено в мережу Bitcoin.</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>Це неперевірений запит платежу.</translation> - </message> - <message> <source>Pay To:</source> <translation>Отримувач:</translation> </message> @@ -2158,8 +2160,8 @@ Address: %4 <translation>&Підписати повідомлення</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>Ви можете підписувати повідомлення зі своїми адресами, щоб довести, що ви є їх власником. Остерігайтеся підписувати будь-що незрозуміле, так як за допомогою фішинг-атаки вас можуть спробувати обдурити для отримання вашого підпису під чужими словами. Підписуйте тільки ті повідомлення, з якими ви повністю згодні.</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Ви можете підписувати повідомлення/угоди своїми адресами, щоб довести можливість отримання біткоінів, що будуть надіслані на них. Остерігайтеся підписувати будь-що нечітке чи неочікуване, так як за допомогою фішинг-атаки вас можуть спробувати ввести в оману для отримання вашого підпису під чужими словами. Підписуйте лише чіткі твердження, з якими ви повністю згодні.</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2211,11 +2213,11 @@ Address: %4 </message> <message> <source>&Verify Message</source> - <translation>Перевірити повідомлення</translation> + <translation>П&еревірити повідомлення</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>Введіть нижче адресу підпису, повідомлення (впевніться, що ви точно скопіювали символи завершення рядку, табуляцію, пробіли тощо) та підпис для перевірки повідомлення. Впевніться, що в підпис не було додано зайвих символів: це допоможе уникнути атак типу «людина посередині».</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Введіть нижче адресу отримувача, повідомлення (впевніться, що ви точно скопіювали символи завершення рядка, табуляцію, пробіли тощо) та підпис для перевірки повідомлення. Впевніться, що в підпис не було додано зайвих символів: це допоможе уникнути атак типу «людина посередині». Зауважте, що це лише засвідчує можливість отримання транзакцій підписувачем, але не в стані підтвердити джерело жодної транзакції!</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2227,7 +2229,7 @@ Address: %4 </message> <message> <source>Verify &Message</source> - <translation>Перевірити повідомлення</translation> + <translation>Пере&вірити повідомлення</translation> </message> <message> <source>Reset all verify message fields</source> @@ -2432,7 +2434,7 @@ Address: %4 </message> <message> <source>Inputs</source> - <translation>витрати</translation> + <translation>Входи</translation> </message> <message> <source>Amount</source> @@ -2481,10 +2483,6 @@ Address: %4 <translation>Тип</translation> </message> <message> - <source>Address</source> - <translation>Адреса</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Незрілі (%1 підтверджень, будуть доступні після %2)</translation> </message> @@ -2513,6 +2511,10 @@ Address: %4 <translation>Поза мережею</translation> </message> <message> + <source>Label</source> + <translation>Назва</translation> + </message> + <message> <source>Unconfirmed</source> <translation>Не підтверджено</translation> </message> @@ -2569,8 +2571,8 @@ Address: %4 <translation>Показує, чи було залучено адресу для спостереження в цій транзакції.</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Адреса отримувача транзакції.</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Призначення транзакції (визначається користувачем).</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2645,11 +2647,11 @@ Address: %4 </message> <message> <source>Copy amount</source> - <translation>Копіювати кількість</translation> + <translation>Скопіювати суму</translation> </message> <message> <source>Copy transaction ID</source> - <translation>Копіювати ID транзакції </translation> + <translation>Скопіювати ID транзакції </translation> </message> <message> <source>Edit label</source> @@ -2823,16 +2825,16 @@ Address: %4 <translation>Поширюється за ліцензією MIT, додаткова інформація міститься у файлі COPYING та за адресою <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Ввійти в режим регресивного тестування, що використовує спеціальний ланцюг з миттєвим знаходженням блоків.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Виконати команду, коли транзакція гаманця зміниться (замість %s в команді буде підставлено ідентифікатор транзакції)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>В цьому режимі -genproclimit встановлює кількість блоків, що можуть бути згенеровані негайно.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Максимальна загальна комісія за одну транзакцію; занадто низьке значення може скасувати відправку великих транзакцій (типово: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>Зменшити вимоги до наявного простору на носії даних за допомогою скорочення ланцюжка (видалення старих блоків). Цей режим вимикає підтримку гаманця та є несумісним з параметром -txindex. Увага: при поверненні до типового значення видалені частини ланцюжка буде повторно завантажено. (типово: 0 = вимкнути скорочення ланцюжка, >%u = очікуваний розмір файлів блоків в МіБ)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2847,6 +2849,14 @@ Address: %4 <translation>Неможливо прив'язатися до %s на цьому комп'ютері. Можливо, Bitcoin Core вже запущено.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>УВАГА: аномально висока кількість згенерованих блоків, %d блок(ів) було отримано за останні %d годин(и) (має бути %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>УВАГА: перевірте ваше мережеве з'єднання, %d блок(ів) було отримано за останні %d годин(и) (має бути %d)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Увага: встановлено занадто велику комісію (-paytxfee). Комісія зніматиметься кожен раз коли ви проводитимете транзакції.</translation> </message> @@ -2888,7 +2898,7 @@ Address: %4 </message> <message> <source>Connect only to the specified node(s)</source> - <translation>Підключитись лише до вказаного вузла</translation> + <translation>Підключитись лише до вказаного вузла/вузлів</translation> </message> <message> <source>Connection options:</source> @@ -2903,10 +2913,6 @@ Address: %4 <translation>Параметри тестування/налагодження:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Визначити власну IP-адресу (типово: 1 при прослуховуванні та за відсутності -externalip)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>Не завантажувати гаманець та вимкнути звернення до нього через RPC</translation> </message> @@ -2964,11 +2970,15 @@ Address: %4 </message> <message> <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> - <translation>Підключити тільки до вузлів в мережі <net> (ipv4, ipv6 або onion)</translation> + <translation>Підключатися тільки до вузлів в мережі <net> (ipv4, ipv6 або onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>Перебудувати індекс ланцюжка блоків з поточних файлів blk000??.dat</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>Розмір скороченого ланцюжка блоків не може бути від'ємним. </translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Використання скороченого ланцюжка блоків несумісне з параметром -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2983,10 +2993,6 @@ Address: %4 <translation>Вкажіть файл гаманця (в межах каталогу даних)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Це призначено для інструментів регресивного тестування та розробки додатків.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Намагатись використовувати UPnP для відображення порту, що прослуховується, на роутері (типово: %u)</translation> </message> @@ -3007,6 +3013,10 @@ Address: %4 <translation>Параметри гаманця:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Увага: Поточна версія застаріла, необхідне оновлення!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Вам необхідно перебудувати базу даних з використанням -reindex для того, щоб змінити -txindex</translation> </message> @@ -3035,14 +3045,14 @@ Address: %4 <translation>Не вдалося встановити блокування на каталог даних %s. Bitcoin Core, ймовірно, вже запущений.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Обмежити швидкість передачі безкоштовних транзакцій до <n>*1000 байтів за хвилину (типово: %u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>Створювати нові файли з типовими для системи атрибутами доступу замість маски 077 (діє тільки при вимкненому гаманці)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Визначити власні IP-адреси (типово: 1 при прослуховуванні та за відсутності -externalip або -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Помилка: Не вдалося налаштувати прослуховування вхідних підключень (listen повернув помилку: %s)</translation> </message> @@ -3059,26 +3069,30 @@ Address: %4 <translation>Комісії (в BTC/КБ), що менші за вказану, вважатимуться нульовими (для ретрансляції) (типово: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Комісії (в BTC/КБ), що менші за вказану, вважатимуться нульовими (для створення транзакції) (типово: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Якщо параметр paytxfee не встановлено, включити комісію для отримання перших підтверджень транзакцій протягом n блоків (типово: %u)</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> + <translation>Неприпустима сума для -maxtxfee = <amount>: «%s» ( плата повинна бути, принаймні %s, щоб запобігти зависанню транзакцій)</translation> + </message> + <message> <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> <translation>Максимальний розмір даних в транзакціях носіїв даних, що ми передаємо і добуваємо (за замовчуванням: %u)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>Максимальна загальна плата для використання в одній транзакції, установка занадто низької може перервати великі транзакції(стандартно: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Встановлений розмір ланцюжка блоків є замалим (менший за %d МБ). Будь ласка, виберіть більше число.</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Дізнаватися адреси учасників через DNS при замалій кількості відомих адрес (типово: 1 за відсутності -connect)</translation> </message> <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Надавати випадкові дані доступу для кожного проксі-з'єднання. Це дозволяє ввімкнути ізоляцію потоків Tor'у (типово: %u)</translation> + </message> + <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Встановити максимальний розмір транзакцій з високим пріоритетом та низькою комісією (в байтах) (типово: %d)</translation> </message> @@ -3087,6 +3101,10 @@ Address: %4 <translation>Встановити кількість потоків для генерації монет (-1 = кількості ядер, типово: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Залишок від суми транзакції зі сплатою комісії занадто малий </translation> + </message> + <message> <source>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.</source> <translation>Цей продукт включає в себе програмне забезпечення, розроблене в рамках проекту OpenSSL <https://www.openssl.org/>, криптографічне програмне забезпечення, написане Еріком Янгом, та функції для роботи з UPnP, написані Томасом Бернардом.</translation> </message> @@ -3127,14 +3145,34 @@ rpcpassword=%s <translation>Учасники, що знаходяться в білому списку, не можуть бути заблоковані за DoS та їхні транзакції завжди ретранслюватимуться (навіть якщо вони є в пам'яті), що може бути корисним, наприклад, для шлюзу</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Вам необхідно перебудувати базу даних з використанням -reindex для завантаження повного ланцюжка блоків.</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(типово: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Приймати публічні REST-запити (типово: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Активація найкращого ланцюжка...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Використання гаманця зі скороченим ланцюжком блоків неможливе.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Не вдалося розпізнати адресу для -whitebind: «%s»</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Обрати каталог даних під час запуску (типово: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>Підключитись через SOCKS5-проксі</translation> </message> @@ -3151,6 +3189,10 @@ rpcpassword=%s <translation>Помилка при завантаженні wallet.dat: Гаманець потребує новішої версії Bitcoin Core</translation> </message> <message> + <source>Error reading from database, shutting down.</source> + <translation>Помилка читання бази даних, припиняю роботу.</translation> + </message> + <message> <source>Error: Unsupported argument -tor found, use -onion.</source> <translation>Помилка: Параметр -tor не підтримується, використовуйте -onion</translation> </message> @@ -3168,7 +3210,7 @@ rpcpassword=%s </message> <message> <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> - <translation>Неприпустима сума для -maxtxfee = <amount>: '%s'</translation> + <translation>Неприпустима сума для -maxtxfee = <amount>: «%s»</translation> </message> <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> @@ -3207,12 +3249,16 @@ rpcpassword=%s <translation>Параметри сервера RPC:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Випадковим чином відкидати 1 з <n> мережевих повідомлень</translation> + <source>RPC support for HTTP persistent connections (default: %d)</source> + <translation>Підтримка RPC для постійних HTTP-з'єднань (типово: %d)</translation> + </message> + <message> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>При запуску перебудувати індекс ланцюжка блоків з поточних файлів blk000??.dat</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Випадковим чином пошкоджувати 1 з <n> мережевих повідомлень</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Отримувати та відображати попередження з мережі (типово: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3223,10 +3269,22 @@ rpcpassword=%s <translation>Не сплачувати комісію за надсилання транзакцій, якщо це можливо (типово: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Вказати кореневі SSL-сертифікати для запиту платежу (типово: -системні-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Встановлення мови, наприклад "de_DE" (типово: системна)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Показати всі налагоджувальні параметри (використання: --help -help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>Показувати заставку під час запуску (типово: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Стискати файл debug.log під час старту клієнта (типово: 1 коли відсутній параметр -debug)</translation> </message> @@ -3235,6 +3293,14 @@ rpcpassword=%s <translation>Підписання транзакції не вдалося</translation> </message> <message> + <source>Start minimized</source> + <translation>Запускати згорнутим</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Неможливо сплатити комісію із-за малої суми транзакції</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Це програмне забезпечення є експериментальним.</translation> </message> @@ -3255,6 +3321,10 @@ rpcpassword=%s <translation>Транзакція занадто велика</translation> </message> <message> + <source>UI Options:</source> + <translation>Параметри інтерфейсу:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Неможливо прив'язатися до %s на цьому комп'ютері (bind повернув помилку: %s)</translation> </message> @@ -3275,10 +3345,6 @@ rpcpassword=%s <translation>Попередження</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>Увага: Поточна версія застаріла, необхідне оновлення!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>Увага: Параметр -benchmark не підтримується та буде проігнорований, використовуйте -debug=bench.</translation> </message> @@ -3339,18 +3405,10 @@ rpcpassword=%s <translation>(1 = утримувати метадані транзакцій (до яких відноситься інформація про власника рахунку та запити платежів), 2 - відкинути)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Записувати зміни в базі даних до файлу кожні <n> мегабайтів (типово: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Рівень ретельності перевірки блоків (0-4, типово: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Записувати в лог-файл пріоритет транзакції та комісію за кБ під час добування блоків (типово: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Утримувати повний індекс транзакцій (використовується RPC-викликом getrawtransaction) (типово: %u)</translation> </message> @@ -3379,18 +3437,10 @@ rpcpassword=%s <translation>Завжди дізнаватися адреси учасників через DNS (типово: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Вимкнути безпечний режим та ігнорувати події, що здатні ввімкнути його (типово: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Помилка при завантаженні wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Ввімкнути безпечний режим (типово: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Генерація монет (типово: %u)</translation> </message> @@ -3407,10 +3457,6 @@ rpcpassword=%s <translation>Помилка в адресі проксі-сервера: «%s»</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Обмежити розмір кешу підписів до <n> записів (типово: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Прослуховувати <port> для JSON-RPC з'єднань (типово: %u, для тестової мережі: %u)</translation> </message> @@ -3423,6 +3469,10 @@ rpcpassword=%s <translation>Підтримувати щонайбільше <n> з'єднань з учасниками (типово: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Дозволити гаманцю розповсюджувати транзакції</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Максимальний розмір вхідного буферу на одне з'єднання, <n>*1000 байтів (типово: %u)</translation> </message> @@ -3431,10 +3481,6 @@ rpcpassword=%s <translation>Максимальний розмір вихідного буферу на одне з'єднання, <n>*1000 байтів (типово: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Приймати тільки той ланцюжок блоків, що не суперечить вбудованим контрольним точкам (типово: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Доповнювати налагоджувальний вивід відміткою часу (типово: %u)</translation> </message> @@ -3447,10 +3493,6 @@ rpcpassword=%s <translation>Ретранслювати не-P2SH транзакції з мультипідписом (типово: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Запустити потік для періодичного збереження даних гаманця (типово: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Файл сертифіката сервера (типово: %s)</translation> </message> @@ -3471,10 +3513,6 @@ rpcpassword=%s <translation>Встановити число потоків для обслуговування викликів RPC (типово: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Встановити прапорець DB_PRIVATE в середовищі бази даних гаманця (типово: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Вказати файл конфігурації (типово: %s)</translation> </message> @@ -3491,10 +3529,6 @@ rpcpassword=%s <translation>Витрачати непідтверджену решту при відправленні транзакцій (типово: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Вимкнутися після імпорту блоків з диску (типово: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Поріг відключення учасників з поганою поведінкою (типово: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ur_PK.ts b/src/qt/locale/bitcoin_ur_PK.ts index edf0190f57..d4242d5e3c 100644 --- a/src/qt/locale/bitcoin_ur_PK.ts +++ b/src/qt/locale/bitcoin_ur_PK.ts @@ -1,7 +1,11 @@ -<TS language="ur_PK" version="2.1"> +<TS language="ur_PK" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>پتہ تبدیل کرے کے لیے دائیاں کلک کریں</translation> + </message> + <message> <source>Create a new address</source> <translation>نیا ایڈریس بنائیں</translation> </message> @@ -10,6 +14,10 @@ <translation>نیا</translation> </message> <message> + <source>Copy the currently selected address to the system clipboard</source> + <translation>سلیکٹڈ پتے کو کمپوٹر کی عارضی جگہ رکھیں</translation> + </message> + <message> <source>&Copy</source> <translation>نقل</translation> </message> @@ -22,6 +30,14 @@ <translation>کاپی پتہ</translation> </message> <message> + <source>Delete the currently selected address from the list</source> + <translation>سلیکٹڈ پتے کو مٹائیں</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>موجودہ ڈیٹا کو فائیل میں محفوظ کریں</translation> + </message> + <message> <source>&Export</source> <translation>برآمد</translation> </message> @@ -30,9 +46,21 @@ <translation>مٹا</translation> </message> <message> + <source>Choose the address to send coins to</source> + <translation>کوئین وصول کرنے والے کا پتہ</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>کوئین بھیجنے والے کا پتہ</translation> + </message> + <message> <source>C&hoose</source> <translation>چننا</translation> </message> + <message> + <source>Sending addresses</source> + <translation>جس پتے پر بھیجنے ہیں</translation> + </message> </context> <context> <name>AddressTableModel</name> @@ -237,8 +265,8 @@ <translation>ٹائپ</translation> </message> <message> - <source>Address</source> - <translation> پتہ</translation> + <source>Label</source> + <translation>چٹ</translation> </message> <message> <source>Sent to</source> @@ -315,6 +343,10 @@ <source>&Export</source> <translation>برآمد</translation> </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>موجودہ ڈیٹا کو فائیل میں محفوظ کریں</translation> + </message> </context> <context> <name>bitcoin-core</name> diff --git a/src/qt/locale/bitcoin_uz@Cyrl.ts b/src/qt/locale/bitcoin_uz@Cyrl.ts index 54592fe902..cc0a4bba08 100644 --- a/src/qt/locale/bitcoin_uz@Cyrl.ts +++ b/src/qt/locale/bitcoin_uz@Cyrl.ts @@ -1,7 +1,11 @@ -<TS language="uz@Cyrl" version="2.1"> +<TS language="uz@Cyrl" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Манзил ёки ёрлиқни таҳрирлаш учун икки марта босинг</translation> + </message> + <message> <source>Create a new address</source> <translation>Янги манзил яратинг</translation> </message> @@ -152,10 +156,6 @@ <translation>Махфий сузни узгартириш</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>Ҳамёнга эски ва янги паролларингизни киритинг.</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>Ҳамённи кодлашни тасдиқлаш</translation> </message> @@ -184,10 +184,6 @@ <translation>Ҳамёнга янги махфий сўз киритинг.<br/>Илтимос, <b>ўнта ёки тасодифий белгили</b> махфий сўздан фойдаланинг ёки <b>саккизта ёки кўпроқ сўзлар</b>дан фойдаланинг.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>Bitcoin кодлаш жараёнини тугатиш учун ёпилади. Ёдда сақланг: ҳамёнингизни кодлаш компьютерингизни зарарлаган зарарли дастурлар томонидан bitcoin тангаларингизни ўғирланишидан тўлиқ ҳимоя қила олмайди.</translation> - </message> - <message> <source>Wallet encryption failed</source> <translation>Ҳамённи кодлаш амалга ошмади</translation> </message> @@ -307,10 +303,6 @@ <translation>Тангаларни Bitcoin манзилига жўнатиш</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>Bitcoin учун мослаш танловларини ўзгартириш</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>Ҳамённи бошқа манзилга заҳиралаш</translation> </message> @@ -487,18 +479,6 @@ <translation>Кирувчи операция</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Санаси: %1 -Миқдори: %2 -Тури: %3 -Манзили: %4 -</translation> - </message> - <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Ҳамён <b>кодланган</b> ва вақтинча <b>қулфдан чиқарилган</b></translation> </message> @@ -689,10 +669,6 @@ Address: %4 <translation>йўқ</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>Агар ўтказманинг ҳажми 1000 байтдан ошса, ёрлиқ қизаради.</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>Бу дегани солиқ ҳар кб учун камида %1 талаб қилинади.</translation> </message> @@ -705,14 +681,6 @@ Address: %4 <translation>Юқори муҳимликка эга бўлган ўтказмалар тезда блокнинг ичига қўшимча олади.</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Агар муҳимлиги "ўртача"дан паст бўлса, ушбу ёрлиқ қизил бўлиб ёнади.</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>Агар қабул қилувчи %1дан кичик миқдорни қабул қилса, ушбу ёрлиқ қизил бўлиб ёнади.</translation> - </message> - <message> <source>(no label)</source> <translation>(Ёрлик мавжуд эмас)</translation> </message> @@ -829,22 +797,6 @@ Address: %4 <source>command-line options</source> <translation>буйруқлар қатори орқали мослаш</translation> </message> - <message> - <source>UI options</source> - <translation>UI мосламалари</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Йиғилганларни бошлаш</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Тўлов сўровлари учун SSL асос сертификатларини ўрнатиш (стандарт: -system-)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Ишга тушиш вақтида маълумотлар директориясини танлаш (стандарт: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -919,14 +871,6 @@ Address: %4 <translation>&Асосий</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>Тизимга киргандан сўнг Bitcoin дастури автоматик ишга туширилсин.</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>Тизимга кирганда Bitcoin &ишга туширилсин</translation> - </message> - <message> <source>Size of &database cache</source> <translation>&Маълумотлар базаси кеши</translation> </message> @@ -991,10 +935,6 @@ Address: %4 <translation>Фойдаланувчи интерфейси &тили:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>Фойдаланувчи тили интерфесини шу ерда ўрнатиш мумкин. TУшбу созлама Bitcoin қайта ишга туширилганда кучга киради.</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>Миқдорларни кўрсатиш учун &қисм:</translation> </message> @@ -1023,10 +963,6 @@ Address: %4 <translation>Ўзгаришлар амалга ошиши учун мижозни қайта ишга тушириш талаб қилинади.</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>Мижоз ўчирилади. Давом эттиришни хоҳлайсизми?</translation> - </message> - <message> <source>This change would require a client restart.</source> <translation>Ушбу ўзгариш мижозни қайтадан ишга туширишни талаб қилади.</translation> </message> @@ -1123,14 +1059,6 @@ Address: %4 <translation>%1 с</translation> </message> <message> - <source>NETWORK</source> - <translation>ТАРМОҚ</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>НОМАЪЛУМ</translation> - </message> - <message> <source>None</source> <translation>Йўқ</translation> </message> @@ -1293,18 +1221,10 @@ Address: %4 <translation>Тузатиш журнали файли</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Жорий махлумотлар директориясидан Bitcoin тузатиш журнали файлини очинг. Бу катта журнал файллари учун бир неча сонияни олиши мумкин.</translation> - </message> - <message> <source>Clear console</source> <translation>Терминални тозалаш</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>Bitcoin RPC терминлга хуш келибсиз.</translation> - </message> - <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Тарихни кўриш учун тепага ва пастга кўрсаткичларидан фойдаланинг, экранни тозалаш учун <b>Ctrl-L</b> тугмалар бирикмасидан фойдаланинг.</translation> </message> @@ -1709,10 +1629,6 @@ Address: %4 <translation>Тури</translation> </message> <message> - <source>Address</source> - <translation>Манзил</translation> - </message> - <message> <source>Open until %1</source> <translation>%1 гача очиш</translation> </message> @@ -1729,6 +1645,10 @@ Address: %4 <translation>Яратилди, аммо қабул қилинмади</translation> </message> <message> + <source>Label</source> + <translation>Ёрлиқ</translation> + </message> + <message> <source>Received with</source> <translation>Ёрдамида қабул қилиш</translation> </message> @@ -1761,10 +1681,6 @@ Address: %4 <translation>Пул ўтказмаси тури</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>Ўтказиладиган жараён манзили.</translation> - </message> - <message> <source>Amount removed from or added to balance.</source> <translation>Миқдор ўчирилган ёки балансга қўшилган.</translation> </message> @@ -1935,10 +1851,22 @@ Address: %4 <translation>Синов тармоғидан фойдаланинг</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Ишга тушиш вақтида маълумотлар директориясини танлаш (стандарт: 0)</translation> + </message> + <message> <source>Information</source> <translation>Маълумот</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Тўлов сўровлари учун SSL асос сертификатларини ўрнатиш (стандарт: -system-)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Йиғилганларни бошлаш</translation> + </message> + <message> <source>Username for JSON-RPC connections</source> <translation>JSON-RPC уланишлари учун фойдаланувчи номи</translation> </message> diff --git a/src/qt/locale/bitcoin_vi.ts b/src/qt/locale/bitcoin_vi.ts index 56962bc5ad..64d11d4645 100644 --- a/src/qt/locale/bitcoin_vi.ts +++ b/src/qt/locale/bitcoin_vi.ts @@ -1,4 +1,4 @@ -<TS language="vi" version="2.1"> +<TS language="vi" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -6,10 +6,22 @@ <translation>Tạo một địa chỉ mới</translation> </message> <message> + <source>&New</source> + <translation>Tạo mới</translation> + </message> + <message> <source>Copy the currently selected address to the system clipboard</source> <translation>Sao chép các địa chỉ đã được chọn vào bộ nhớ tạm thời của hệ thống</translation> </message> <message> + <source>&Copy</source> + <translation>Sao chép</translation> + </message> + <message> + <source>&Copy Address</source> + <translation>Sao chép địa chỉ</translation> + </message> + <message> <source>&Delete</source> <translation>&Xóa</translation> </message> @@ -161,8 +173,8 @@ <context> <name>TransactionTableModel</name> <message> - <source>Address</source> - <translation>Địa chỉ</translation> + <source>Label</source> + <translation>Nhãn dữ liệu</translation> </message> </context> <context> diff --git a/src/qt/locale/bitcoin_vi_VN.ts b/src/qt/locale/bitcoin_vi_VN.ts index 0c4476b4fc..7bcded7448 100644 --- a/src/qt/locale/bitcoin_vi_VN.ts +++ b/src/qt/locale/bitcoin_vi_VN.ts @@ -1,4 +1,4 @@ -<TS language="vi_VN" version="2.1"> +<TS language="vi_VN" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -258,18 +258,6 @@ <source>Incoming transaction</source> <translation>Giao dịch đang tới</translation> </message> - <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 -</source> - <translation>Ngày: %1 -Lượng: %2 -Loại: %3 -Địa chỉ: %4 -</translation> - </message> </context> <context> <name>ClientModel</name> @@ -470,10 +458,6 @@ Loại: %3 <source>Amount</source> <translation>Lượng</translation> </message> - <message> - <source>NETWORK</source> - <translation>NETWORK</translation> - </message> </context> <context> <name>QRImageWidget</name> @@ -621,8 +605,8 @@ Loại: %3 <translation>Ngày tháng</translation> </message> <message> - <source>Address</source> - <translation>Địa chỉ</translation> + <source>Label</source> + <translation>Nhãn</translation> </message> </context> <context> diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index ddc8168ad9..4470b2601b 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -1,4 +1,4 @@ -<TS language="zh_CN" version="2.1"> +<TS language="zh_CN" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -67,7 +67,7 @@ </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>这是您用来付款的比特币地址。在付款前,请总是核实付款金额和收款地址。</translation> + <translation>这是您用来付款的比特币地址。在付款前,请仔细核实付款金额和收款地址。</translation> </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> @@ -156,10 +156,6 @@ <translation>更改密码</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>请输入该钱包的旧密码与新密码。</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>确认加密钱包</translation> </message> @@ -172,6 +168,10 @@ <translation>您确定需要为钱包加密吗?</translation> </message> <message> + <source>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.</source> + <translation>比特币核心现在将关闭以完成加密过程。请记住,在您的计算机被恶意软件感染的情况下,加密不能完全保护您的比特币免于被盗。</translation> + </message> + <message> <source>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.</source> <translation>重要提示:您以前备份的钱包文件应该替换成最新生成的加密钱包文件(重新备份)。从安全性上考虑,您以前备份的未加密的钱包文件,在您使用新的加密钱包后将无效,请重新备份。</translation> </message> @@ -188,8 +188,8 @@ <translation>请输入新的钱包密码. <br/>密码须包含<b>10个以上字符</b>,或<b>8个以上单词</b>.</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>比特币客户端将关闭软件以完成加密过程。请您谨记:钱包加密并不是万能的,电脑中毒等原因仍可能导致您的比特币意外丢失。</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>请输入钱包的旧密码与新密码。</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>向一个比特币地址发送比特币</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>设置选项</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>备份钱包到其他文件夹</translation> </message> @@ -403,6 +399,10 @@ <translation>关于比特币核心(&A)</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>修改比特币核心的配置选项</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>显示用过的发送地址和标签的列表</translation> </message> @@ -431,6 +431,10 @@ <translation>沒有可用的区块来源...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>已处理 %n 个交易历史数据块。</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n 小时</numerusform></translation> </message> @@ -478,35 +482,49 @@ <source>Up to date</source> <translation>已是最新</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>已处理 %n 个交易历史数据块。</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>更新中...</translation> </message> <message> - <source>Sent transaction</source> - <translation>发送交易</translation> + <source>Date: %1 +</source> + <translation>日期: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>流入交易</translation> + <source>Amount: %1 +</source> + <translation>金额: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>日期: %1 -金额: %2 -类别: %3 -地址: %4 + <translation>类型: %1 </translation> </message> <message> + <source>Label: %1 +</source> + <translation>标签: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>地址: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>发送交易</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>流入交易</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>钱包已被<b>加密</b>,当前为<b>解锁</b>状态</translation> </message> @@ -697,6 +715,18 @@ Address: %4 <translation>无</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>如果交易规模大于 1000 字节,此标签将变为红色。</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>如果优先级小于“中等”,此标签将变为红色。</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>如果任何接收人收到的金额小于 %1,此标签将变为红色。</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>可能会有 正负 %1 聪(satoshi)的偏差 </translation> </message> @@ -709,10 +739,6 @@ Address: %4 <translation>否</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>如果这笔交易大于1000字节,标签会变成红色。</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>这意味着将对交易收取 %1/千字节 的交易费。</translation> </message> @@ -725,14 +751,6 @@ Address: %4 <translation>交易的优先级越高,被矿工收入数据块的速度也越快。</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>如果优先级小于"中位数" ,标签将变成红色。</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>如果收款地址收到小于%1的比特币,标签将变成红色。</translation> - </message> - <message> <source>(no label)</source> <translation>(没有标签)</translation> </message> @@ -853,31 +871,6 @@ Address: %4 <source>command-line options</source> <translation>命令行选项</translation> </message> - <message> - <source>UI options</source> - <translation>UI选项</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>设置语言, 例如“zh-TW”(默认为系统语言)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>启动时最小化 -</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>设置SSL根证书的付款请求(默认:-系统-)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>启动时显示版权页 (缺省: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>在启动时选择数据目录(默认:0)</translation> - </message> </context> <context> <name>Intro</name> @@ -960,14 +953,6 @@ Address: %4 <translation>主要(&M)</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>登录系统后自动开启比特币客户端</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>系统启动时运行(&S)</translation> - </message> - <message> <source>Size of &database cache</source> <translation>数据库缓存大小(&D)</translation> </message> @@ -992,6 +977,14 @@ Address: %4 <translation>代理的 IP 地址 (例如 IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>窗口被关闭时最小化而不是退出应用程序。当此选项启用时,应用程序只会在菜单中选择退出时退出。</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>可以在这里设置用户界面语言。此设置将在重新启动比特币核心后生效。</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>出现在交易的选项卡的上下文菜单项的第三方网址 (例如:区块链接查询) 。 %s的URL被替换为交易哈希。多个的URL需要竖线 | 分隔。</translation> </message> @@ -1016,6 +1009,14 @@ Address: %4 <translation>网络(&N)</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>登录到系统后自动启动比特币核心。</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>系统登录时启动比特币核心(&S)</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = 自动, <0 = 离开很多免费的核心)</translation> </message> @@ -1080,10 +1081,6 @@ Address: %4 <translation>最小化到托盘(&M)</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>当窗口关闭时程序最小化而不是退出。当使用该选项时,程序只能通过在菜单中选择退出来关闭</translation> - </message> - <message> <source>M&inimize on close</source> <translation>单击关闭按钮最小化(&I)</translation> </message> @@ -1096,10 +1093,6 @@ Address: %4 <translation>用户界面语言(&L):</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>在这里设置用户界面的语言。设置将在客户端重启后生效。</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>比特币金额单位(&U):</translation> </message> @@ -1136,8 +1129,8 @@ Address: %4 <translation>更改生效需要重启客户端。</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>客户端即将关闭,确定继续吗?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>客户端即将关闭,您想继续吗?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1222,10 +1215,6 @@ Address: %4 <source>Current total balance in watch-only addresses</source> <translation>观察地址(watch-only address)中的当前总余额 </translation> </message> - <message> - <source>out of sync</source> - <translation>数据同步中</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1246,10 +1235,6 @@ Address: %4 <translation>付款请求所在的网络与当前客户端所在的网络不匹配。</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>支付请求已超时</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>支付请求未成形。</translation> </message> @@ -1282,10 +1267,18 @@ Address: %4 <translation>付款请求文件无法读取!可能是付款请求文件不合格。</translation> </message> <message> + <source>Payment request expired.</source> + <translation>支付请求已过期。</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>不支持到自定义付款脚本的未验证付款请求。</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>无效的支付请求。</translation> + </message> + <message> <source>Refund from %1</source> <translation>退款来自 %1</translation> </message> @@ -1325,8 +1318,8 @@ Address: %4 <translation>用户代理</translation> </message> <message> - <source>Address/Hostname</source> - <translation>地址/主机名</translation> + <source>Node/Service</source> + <translation>节点/服务</translation> </message> <message> <source>Ping Time</source> @@ -1360,14 +1353,6 @@ Address: %4 <translation>%1 秒</translation> </message> <message> - <source>NETWORK</source> - <translation>网络</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>未知</translation> - </message> - <message> <source>None</source> <translation>无</translation> </message> @@ -1458,6 +1443,10 @@ Address: %4 <translation>当前数据块数量</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>从当前的数据目录打开比特币核心调试日志文件。对于较大的日志文件,这可能需要几秒钟。</translation> + </message> + <message> <source>Received</source> <translation>收到</translation> </message> @@ -1526,6 +1515,10 @@ Address: %4 <translation>Ping 时间</translation> </message> <message> + <source>Time Offset</source> + <translation>时间偏移</translation> + </message> + <message> <source>Last block time</source> <translation>上一数据块时间</translation> </message> @@ -1566,16 +1559,12 @@ Address: %4 <translation>调试日志文件</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>打开当前目录中的调试日志文件。日志文件大的话可能要等上几秒钟。</translation> - </message> - <message> <source>Clear console</source> <translation>清空控制台</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>欢迎来到 RPC 控制台。</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>欢迎使用 比特币核心 RPC 控制台。</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1866,14 +1855,6 @@ Address: %4 <translation>收起 费用设置 </translation> </message> <message> - <source>Minimize</source> - <translation>最小化</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>如果自定义交易费设置为 1000聪而交易大小只有250字节,则“每千字节" 模式只支付250聪交易费, 而"最少"模式则支付1000聪。 大于1000字节的交易按每千字节付费。</translation> - </message> - <message> <source>per kilobyte</source> <translation>每kb</translation> </message> @@ -1882,6 +1863,10 @@ Address: %4 <translation>如果自定义交易费设置为 1000聪而交易大小只有250字节,则“每千字节" 模式只支付250聪交易费, 而"最少"模式则支付1000聪。 大于1000字节的交易按每千字节付费。</translation> </message> <message> + <source>Hide</source> + <translation>隐藏</translation> + </message> + <message> <source>total at least</source> <translation>最小额 </translation> </message> @@ -2002,10 +1987,6 @@ Address: %4 <translation>或</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>收款人地址不合法,请检查。</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>支付金额必须大于0。</translation> </message> @@ -2018,10 +1999,6 @@ Address: %4 <translation>计入 %1 交易费后的金额超出您的账上余额。</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>发现重复的地址, 每次只能对同一地址发送一次。</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>交易创建失败!</translation> </message> @@ -2030,16 +2007,28 @@ Address: %4 <translation>错误:该交易被拒绝!发生这种错误的原因可能是:钱包中的比特币已经被用掉,有可能您复制了wallet.dat钱包文件,然后用复制的钱包文件支付了比特币,但是这个钱包文件中没有记录。</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> - <translation>高于 %1的交易费 将视为 过高的交易费。</translation> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>超过 %1 的交易费被认为是荒谬的高费率。</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>支付请求已过期。</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>预计 %n 个数据块后被确认。</numerusform></translation> </message> <message> <source>Pay only the minimum fee of %1</source> <translation>只支付最小费用 %1</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>预计%1 个数据块后确认。</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>接收人地址无效。请重新检查。</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>发现重复地址:每个地址应该只使用一次。</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2113,12 +2102,24 @@ Address: %4 <translation>移除此项</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>交易费将从发送总额中扣除。接收人将收到比您在金额框中输入的更少的比特币。如果选中了多个收件人,交易费平分。</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>从金额中减去交易费(&U)</translation> + </message> + <message> <source>Message:</source> <translation>消息:</translation> </message> <message> - <source>This is a verified payment request.</source> - <translation>这是个有效的支付请求。</translation> + <source>This is an unauthenticated payment request.</source> + <translation>这是一个未经验证的支付请求。</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>这是一个已经验证的支付请求。</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2129,10 +2130,6 @@ Address: %4 <translation>bitcoin:URI 附带的备注信息,将会和交易一起存储,备查。 注意:该消息不会通过比特币网络传输。</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>这是个非有效的支付请求。</translation> - </message> - <message> <source>Pay To:</source> <translation>支付给:</translation> </message> @@ -2163,8 +2160,8 @@ Address: %4 <translation>签名消息(&S)</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>您可以用你的地址对消息进行签名,以证明您是该地址的所有人。注意不要对模棱两可的消息签名,以免遭受钓鱼式攻击。请确保消息内容准确的表达了您的真实意愿。</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>您可以用你的地址对消息/协议进行签名,以证明您可以接收发送到该地址的比特币。注意不要对任何模棱两可或者随机的消息进行签名,以免遭受钓鱼式攻击。请确保消息内容准确的表达了您的真实意愿。</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2219,8 +2216,8 @@ Address: %4 <translation>验证消息(&V)</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>在下面输入签名地址,消息(请确保换行符、空格符、制表符等等一个不漏)和签名以验证消息。请确保签名信息准确,提防中间人攻击。</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>请在下面输入接收者地址、消息(确保换行符、空格符、制表符等完全相同)和签名以验证消息。请仔细核对签名信息,以提防中间人攻击。请注意,这只是证明接收方签名的地址,它不能证明任何交易!</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2486,10 +2483,6 @@ Address: %4 <translation>类别</translation> </message> <message> - <source>Address</source> - <translation>地址</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>未成熟 (%1 个确认,将在 %2 个后可用)</translation> </message> @@ -2518,6 +2511,10 @@ Address: %4 <translation>掉线</translation> </message> <message> + <source>Label</source> + <translation>标签</translation> + </message> + <message> <source>Unconfirmed</source> <translation>未确认的 </translation> </message> @@ -2574,8 +2571,8 @@ Address: %4 <translation>该交易中是否涉及 观察地址(watch-only address)。</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>交易目的地址。</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>用户定义的该交易的意图/目的。</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2834,16 +2831,16 @@ Address: %4 <translation>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>进入回归测试模式,它采用一种特殊的可立即解决的区块链模拟情况。</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>当最佳区块变化时执行命令 (命令行中的 %s 会被替换成区块哈希值)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>在-genproclimit这种模式下控制产出多少区块</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>单次交易最多使用交易费;设置太低可能导致大宗交易中止 (默认: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>通过修剪(删除)旧数据块减少存储需求。此模式将禁用钱包支持,并与 -txindex 不兼容。警告:还原此设置需要重新下载整个数据链。(默认: 0 = 禁用修剪数据块, >%u = 数据块文件目标大小,单位 MiB)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2858,6 +2855,14 @@ Address: %4 <translation>无法 %s的绑定到电脑上,比特币核心钱包可能已经在运行。</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>警告:数据块生成数量异常,最近 %d 小时收到了 %d 个数据块(预期为 %d 个)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>警告:请检查您的网络连接,最近 %d 小时收到了 %d 个数据块(预期为 %d 个)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>警告:-paytxfee 交易费设置得太高了!每笔交易都将支付交易费。</translation> </message> @@ -2914,10 +2919,6 @@ Address: %4 <translation>调试/测试选项:</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>发现自己的IP地址(缺省:不带 -externalip 参数监听时设置为1)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>不要加载钱包和禁用钱包的 RPC 调用</translation> </message> @@ -2978,8 +2979,12 @@ Address: %4 <translation>只连接 <net>网络中的节点 (ipv4, ipv6 或 onion) </translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>重新为当前的blk000??.dat文件建立索引</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>修剪不能配置一个负数。</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>修剪模式与 -txindex 不兼容。</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2994,10 +2999,6 @@ Address: %4 <translation>指定钱包文件(数据目录内)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>这是用于回归测试和应用开发目的。</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>使用UPnp映射监听端口 (默认: %u) </translation> </message> @@ -3018,6 +3019,10 @@ Address: %4 <translation>钱包选项:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>警告:此版本已过时,必须升级!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>您需要将 -reindex 改为 -txindex 以重建数据库</translation> </message> @@ -3046,14 +3051,14 @@ Address: %4 <translation>无法获取数据目录的 %s. 比特币核心钱包可能已经在运行.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>创建系统默认权限的文件,而不是 umask 077 (只在关闭钱包功能时有效) </translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>发现自己的 IP 地址(默认: 监听并且无 -externalip 或 -proxy 时为 1)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>错误:监听外部连接失败 (监听返回错误 %s) </translation> </message> @@ -3070,10 +3075,6 @@ Address: %4 <translation>交易费(BTC/kb)比这更小的交易在转发时将被视为零费交易 (默认: %s) </translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>交易费(BTC/kb)比这更小的交易在生成交易时将被视为零费交易 (默认: %s) </translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>如果未设置交易费用,自动添加足够的交易费以确保交易在平均n个数据块内被确认 (默认: %u) </translation> </message> @@ -3086,16 +3087,16 @@ Address: %4 <translation>Maximum size of data in data carrier transactions we relay and mine (default: %u)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>单笔钱包交易中最多使用的交易费,设置过低可能中止大笔交易 (默认: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>修剪被配置为比最小值 %d MB 更低。请使用更大的数字。</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>通过DNS查询每个地址,如果短地址 (默认值: 1 除非 -连接)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>对交易免费或低交易费请求高优先级 (默认:%u)</translation> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>为每个代理连接随机化凭据。这将启用 Tor 流隔离 (默认: %u)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3106,6 +3107,10 @@ Address: %4 <translation>设置比特币生成线程数 ( -1=所有核, 默认: %d) </translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>在交易费被扣除后发送的交易金额太小</translation> + </message> + <message> <source>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.</source> <translation>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.</translation> </message> @@ -3146,14 +3151,34 @@ rpcpassword=%s <translation>白名单节点不能被DoS banned ,且转发所有来自他们的交易(即便这些交易已经存在于mempool中),常用于网关 </translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>您需要使用 -reindex 重新构建数据库以返回未修剪的模式。这将重新下载整个区块链</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(默认: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>接受公共 REST 请求 (默认: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>正在激活最佳数据链...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>不能在修剪模式下运行一个钱包。</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>无法解析 -whitebind 地址: '%s'</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>在启动时选择数据目录(默认:0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>通过 SOCKS5 代理连接</translation> </message> @@ -3230,12 +3255,12 @@ rpcpassword=%s <translation>RPC 支持 HTTP 持久连接 (默认: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>随机每1个丢失测试<n>网络信息</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>启动时重新为当前的 blk000??.dat 文件建立索引</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>随机每1个模拟测试<n>网络信息</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>收到并且显示P2P网络的告警(默认:%u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3246,10 +3271,22 @@ rpcpassword=%s <translation>发送时尽可能 不支付交易费用 (默认: %u) </translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>设置SSL根证书的付款请求(默认:-系统-)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>设置语言, 例如“zh-TW”(默认为系统语言)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>显示所有调试选项 (用法: --帮助 -帮助调试)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>启动时显示版权页 (缺省: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>客户端启动时压缩debug.log文件(缺省:no-debug模式时为1)</translation> </message> @@ -3258,6 +3295,15 @@ rpcpassword=%s <translation>签署交易失败</translation> </message> <message> + <source>Start minimized</source> + <translation>启动时最小化 +</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>交易金额太小,不足以支付交易费</translation> + </message> + <message> <source>This is experimental software.</source> <translation>这是实验性的软件。</translation> </message> @@ -3278,6 +3324,10 @@ rpcpassword=%s <translation>交易太大</translation> </message> <message> + <source>UI Options:</source> + <translation>界面选项:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>无法在此计算机上绑定 %s (绑定返回错误 %s)</translation> </message> @@ -3298,10 +3348,6 @@ rpcpassword=%s <translation>警告</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>警告:该软件版本已过时,请升级!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>警告:不支持的参数 -benchmark 已忽略,请使用 -debug=bench。</translation> </message> @@ -3364,18 +3410,10 @@ rpcpassword=%s <translation>(1 = 保留 tx meta data , 如 account owner 和 payment request information, 2 = 不保留 tx meta data) </translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>数据块验证 严密级别 -checkblocks (0-4, 默认: %u) </translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>挖矿时,记录交易优先级 和 每kb交易费 (默认: %u) </translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>维护一份完整的交易索引, 用于 getrawtransaction RPC调用 (默认: %u)</translation> </message> @@ -3400,18 +3438,10 @@ rpcpassword=%s <translation>可接受的密码算法 (默认: %s) </translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>禁止使用安全模式,重新写入一个真正的安全模式日志(默认: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>wallet.dat 钱包文件加载出错</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>强制安全模式 (默认: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>生成比特币 (默认: %u)</translation> </message> @@ -3428,10 +3458,6 @@ rpcpassword=%s <translation>无效的代理地址:%s</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>签名缓冲区大小限制最多 <n> 条 (默认: %u) </translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>使用 <port>端口监听 JSON-RPC 连接 (默认: %u ; testnet: %u) </translation> </message> @@ -3444,6 +3470,10 @@ rpcpassword=%s <translation>保留最多 <n> 条节点连接 (默认: %u) </translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>钱包广播事务处理</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>每个连接的最大接收缓存,<n>*1000 字节 (默认: %u)</translation> </message> @@ -3452,10 +3482,6 @@ rpcpassword=%s <translation>每个连接的最大发送缓存,<n>*1000 字节 (默认: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>仅接受符合客户端检查点设置 的数据块链 (默认: %u) </translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>输出调试信息时,前面加上时间戳 (默认: %u)</translation> </message> @@ -3468,10 +3494,6 @@ rpcpassword=%s <translation>是否转发 非P2SH格式的多签名交易 (默认: %u) </translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>运行一个线程,定时清理钱包 (默认: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>服务器证书文件 (默认: %s) </translation> </message> @@ -3492,10 +3514,6 @@ rpcpassword=%s <translation>设置RPC服务线程数 (默认: %d) </translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>指定配置文件 (默认: %s) </translation> </message> @@ -3512,10 +3530,6 @@ rpcpassword=%s <translation>付款时允许使用未确认的零钱 (默认: %u) </translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>从磁盘导入数据块后退出 (默认: %u) </translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>断开 非礼节点的阀值 (默认: %u) </translation> </message> diff --git a/src/qt/locale/bitcoin_zh_HK.ts b/src/qt/locale/bitcoin_zh_HK.ts index dfdbb7d1da..7062377f45 100644 --- a/src/qt/locale/bitcoin_zh_HK.ts +++ b/src/qt/locale/bitcoin_zh_HK.ts @@ -1,4 +1,4 @@ -<TS language="zh_HK" version="2.1"> +<TS language="zh_HK" version="2.0"> <context> <name>AddressBookPage</name> </context> diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index 606eded663..9a93d896fe 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -1,4 +1,4 @@ -<TS language="zh_TW" version="2.1"> +<TS language="zh_TW" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -156,10 +156,6 @@ <translation>改變密碼</translation> </message> <message> - <source>Enter the old and new passphrase to the wallet.</source> - <translation>請輸入錢包的舊密碼及新密碼。</translation> - </message> - <message> <source>Confirm wallet encryption</source> <translation>確認錢包加密</translation> </message> @@ -172,6 +168,10 @@ <translation>你確定要把錢包加密嗎?</translation> </message> <message> + <source>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.</source> + <translation>位元幣核心現在要關閉,好完成加密程序。請注意,加密錢包不能完全防止入侵你的電腦的惡意程式偷取位元幣。</translation> + </message> + <message> <source>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.</source> <translation>重要: 請改用新產生有加密的錢包檔,來取代舊錢包檔的備份。為了安全性的理由,當你開始使用新的有加密的錢包後,舊錢包檔的備份就不能再使用了。</translation> </message> @@ -188,8 +188,8 @@ <translation>輸入錢包的新密碼。<br/>密碼請用<b>10 個以上的字元</b>,或是<b>8 個以上的字詞</b>。</translation> </message> <message> - <source>Bitcoin 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.</source> - <translation>位元幣軟體現在要關閉,好完成加密程序。請注意,加密錢包不能完全防止入侵你的電腦的惡意程式偷取位元幣。</translation> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>請輸入錢包的舊密碼和新密碼。</translation> </message> <message> <source>Wallet encryption failed</source> @@ -311,10 +311,6 @@ <translation>付錢給一個位元幣位址</translation> </message> <message> - <source>Modify configuration options for Bitcoin</source> - <translation>修改位元幣軟體的設定選項</translation> - </message> - <message> <source>Backup wallet to another location</source> <translation>把錢包備份到其它地方</translation> </message> @@ -403,6 +399,10 @@ <translation>關於位元幣核心</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>修改位元幣核心的設定選項</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>顯示已使用過的付款位址和標記的清單</translation> </message> @@ -431,6 +431,10 @@ <translation>沒有可用的區塊來源...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>已經處理了 %n 個區塊的交易紀錄。</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n 個小時</numerusform></translation> </message> @@ -478,35 +482,49 @@ <source>Up to date</source> <translation>最新狀態</translation> </message> - <message numerus="yes"> - <source>Processed %n blocks of transaction history.</source> - <translation><numerusform>已經處理了 %n 個區塊的交易紀錄。</numerusform></translation> - </message> <message> <source>Catching up...</source> <translation>正在趕進度...</translation> </message> <message> - <source>Sent transaction</source> - <translation>付款交易</translation> + <source>Date: %1 +</source> + <translation>日期: %1 +</translation> </message> <message> - <source>Incoming transaction</source> - <translation>收款交易</translation> + <source>Amount: %1 +</source> + <translation>金額: %1 +</translation> </message> <message> - <source>Date: %1 -Amount: %2 -Type: %3 -Address: %4 + <source>Type: %1 </source> - <translation>日期: %1 -金額: %2 -種類: %3 -位址: %4 + <translation>種類: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>標記: %1 </translation> </message> <message> + <source>Address: %1 +</source> + <translation>位址: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>付款交易</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>收款交易</translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>錢包<b>已加密</b>並且<b>解鎖中</b></translation> </message> @@ -697,6 +715,18 @@ Address: %4 <translation>無</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>當交易大小大於 1000 位元組時,文字會變紅色。</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>當優先度低於「中等」時,文字會變紅色。</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>當任何一個收款金額小於 %1 時,文字會變紅色。</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>每組輸入可能有 +/- %1 個 satoshi 的誤差。</translation> </message> @@ -709,10 +739,6 @@ Address: %4 <translation>否</translation> </message> <message> - <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>當交易大小大於 1000 位元組時,文字會變紅色。</translation> - </message> - <message> <source>This means a fee of at least %1 per kB is required.</source> <translation>表示每一千位元組(kB)需要至少 %1 的手續費。</translation> </message> @@ -725,14 +751,6 @@ Address: %4 <translation>優先度較高的交易比較有可能被接受放進區塊中。</translation> </message> <message> - <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>當優先度低於「中等」時,文字會變紅色。</translation> - </message> - <message> - <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation>當任何一個收款金額小於 %1 時,文字會變紅色。</translation> - </message> - <message> <source>(no label)</source> <translation>(無標記)</translation> </message> @@ -853,30 +871,6 @@ Address: %4 <source>command-line options</source> <translation>命令列選項</translation> </message> - <message> - <source>UI options</source> - <translation>使用界面選項</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>設定語言,比如說 de_DE (預設值: 系統語系)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>啓動時縮到最小</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>設定付款請求時所使用的 SSL 根憑證 (預設值: 系統憑證庫)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>顯示啓動畫面(預設值: 1)</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>啓動時選擇資料目錄(預設值: 0)</translation> - </message> </context> <context> <name>Intro</name> @@ -959,14 +953,6 @@ Address: %4 <translation>主要</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>在登入系統後自動啓動位元幣軟體。</translation> - </message> - <message> - <source>&Start Bitcoin on system login</source> - <translation>系統登入時啟動位元幣</translation> - </message> - <message> <source>Size of &database cache</source> <translation>資料庫快取大小</translation> </message> @@ -991,6 +977,14 @@ Address: %4 <translation>代理伺服器的網際網路位址(像是 IPv4 的 127.0.0.1 或 IPv6 的 ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>當視窗關閉時,把應用程式縮到最小,而不是結束。當勾選這個選項時,只能夠用選單中的結束來關掉應用程式。</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>可以在這裡設定使用者介面的語言。這個設定在重啓位元幣核心後才會生效。</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>在交易頁籤的情境選單出現的第三方(比如說區塊探索網站)網址連結。網址中的 %s 會被取代為交易的雜湊值。可以用直線符號 | 來分隔多個連結。</translation> </message> @@ -1015,6 +1009,14 @@ Address: %4 <translation>網路</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>在登入系統後自動啓動位元幣核心。</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>系統登入時啟動位元幣核心</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 表示程式自動決定,小於 0 表示保留處理器核心不用的數目)</translation> </message> @@ -1079,10 +1081,6 @@ Address: %4 <translation>縮到最小到通知區域而不是工作列</translation> </message> <message> - <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source> - <translation>當視窗關閉時,把應用程式縮到最小,而不是結束。當勾選這個選項時,只能夠用選單中的結束來關掉應用程式。</translation> - </message> - <message> <source>M&inimize on close</source> <translation>關閉時縮到最小</translation> </message> @@ -1095,10 +1093,6 @@ Address: %4 <translation>使用界面語言:</translation> </message> <message> - <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>可以在這裡設定使用者介面的語言。這個設定在重啓位元幣軟體後才會生效。</translation> - </message> - <message> <source>&Unit to show amounts in:</source> <translation>金額顯示單位:</translation> </message> @@ -1135,8 +1129,8 @@ Address: %4 <translation>需要重新啟動客戶端軟體來讓改變生效。</translation> </message> <message> - <source>Client will be shutdown, do you want to proceed?</source> - <translation>客戶端軟體就要關掉了,繼續做下去嗎?</translation> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>客戶端軟體就要關掉了。繼續做下去嗎?</translation> </message> <message> <source>This change would require a client restart.</source> @@ -1221,10 +1215,6 @@ Address: %4 <source>Current total balance in watch-only addresses</source> <translation>所有只能看位址的目前全部餘額</translation> </message> - <message> - <source>out of sync</source> - <translation>還沒同步</translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1245,10 +1235,6 @@ Address: %4 <translation>付款要求的網路類型跟客戶端不符。</translation> </message> <message> - <source>Payment request has expired.</source> - <translation>付款的要求已經過期了。</translation> - </message> - <message> <source>Payment request is not initialized.</source> <translation>付款的要求沒有完成初始化。</translation> </message> @@ -1281,10 +1267,18 @@ Address: %4 <translation>沒辦法讀取付款要求檔案!可能是無效的檔案造成的。</translation> </message> <message> + <source>Payment request expired.</source> + <translation>付款的要求過期了。</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>不支援含有自訂付款指令碼,且沒驗證過的付款要求。</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>付款的要求無效。</translation> + </message> + <message> <source>Refund from %1</source> <translation>來自 %1 的退款</translation> </message> @@ -1324,8 +1318,8 @@ Address: %4 <translation>使用者代理</translation> </message> <message> - <source>Address/Hostname</source> - <translation>位址/主機名稱</translation> + <source>Node/Service</source> + <translation>節點/服務</translation> </message> <message> <source>Ping Time</source> @@ -1359,14 +1353,6 @@ Address: %4 <translation>%1 秒</translation> </message> <message> - <source>NETWORK</source> - <translation>網路</translation> - </message> - <message> - <source>UNKNOWN</source> - <translation>不明</translation> - </message> - <message> <source>None</source> <translation>無</translation> </message> @@ -1457,6 +1443,10 @@ Address: %4 <translation>目前區塊數</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>從目前的資料目錄下開啓位元幣核心的除錯紀錄檔。當紀錄檔很大時,可能會花好幾秒的時間。</translation> + </message> + <message> <source>Received</source> <translation>收款</translation> </message> @@ -1525,6 +1515,10 @@ Address: %4 <translation>Ping 時間</translation> </message> <message> + <source>Time Offset</source> + <translation>時間差</translation> + </message> + <message> <source>Last block time</source> <translation>最近區塊時間</translation> </message> @@ -1565,16 +1559,12 @@ Address: %4 <translation>除錯紀錄檔</translation> </message> <message> - <source>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>從目前的資料目錄下開啓位元幣軟體的除錯紀錄檔。當紀錄檔很大時,可能會花好幾秒的時間。</translation> - </message> - <message> <source>Clear console</source> <translation>清主控台</translation> </message> <message> - <source>Welcome to the Bitcoin RPC console.</source> - <translation>歡迎使用位元幣 RPC 主控台。</translation> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>歡迎使用位元幣核心 RPC 主控台。</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> @@ -1865,14 +1855,6 @@ Address: %4 <translation>展開手續費設定</translation> </message> <message> - <source>Minimize</source> - <translation>縮小</translation> - </message> - <message> - <source>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 "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>如果自訂手續費設定為 1000 satoshi, 而交易資料大小只有 250 個位元組的話,那麽選擇「每千位元組」就只會付 250 satoshi 的手續費,換做選「總共至少」就會付 1000 satoshi. 但是如果交易資料大小超過一千個位元組,那麽兩者都是每千位元組的費用。</translation> - </message> - <message> <source>per kilobyte</source> <translation>每千位元組</translation> </message> @@ -1881,6 +1863,10 @@ Address: %4 <translation>如果自訂手續費設定為 1000 satoshi, 而交易資料大小只有 250 個位元組的話,那麽選擇「每千位元組」就只會付 250 satoshi 的手續費,換做選「總共至少」就會付 1000 satoshi. 但是如果交易資料大小超過一千個位元組,那麽兩者都是每千位元組的費用。</translation> </message> <message> + <source>Hide</source> + <translation>隱藏</translation> + </message> + <message> <source>total at least</source> <translation>總共最少</translation> </message> @@ -2001,10 +1987,6 @@ Address: %4 <translation>或</translation> </message> <message> - <source>The recipient address is not valid, please recheck.</source> - <translation>收款位址無效,請再檢查看看。</translation> - </message> - <message> <source>The amount to pay must be larger than 0.</source> <translation>付款金額必須大於零。</translation> </message> @@ -2017,10 +1999,6 @@ Address: %4 <translation>包含 %1 的交易手續費後,總金額超過你的餘額了。</translation> </message> <message> - <source>Duplicate address found, can only send to each address once per send operation.</source> - <translation>發現有重複的位址。每個付款動作中,只能付給個別的位址一次。</translation> - </message> - <message> <source>Transaction creation failed!</source> <translation>製造交易失敗了!</translation> </message> @@ -2029,16 +2007,24 @@ Address: %4 <translation>交易被拒絕了!有時候會發生這種錯誤,是因為你錢包中的一些錢已經被花掉了。比如說你複製了錢包檔 wallet.dat, 然後用複製的錢包花掉了錢,你現在所用的原來的錢包中,卻沒有那筆錢已經花掉的紀錄。</translation> </message> <message> - <source>A fee higher than %1 is considered an insanely high fee.</source> - <translation>高於 %1 的手續費會被認為是不正常。</translation> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>高於 %1 的手續費會被認為是不合理。</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>付款的要求過期了。</translation> </message> <message> <source>Pay only the minimum fee of %1</source> <translation>只付最低手續費 %1</translation> </message> <message> - <source>Estimated to begin confirmation within %1 block(s).</source> - <translation>預計可在 %1 個區塊內開始確認。</translation> + <source>The recipient address is not valid. Please recheck.</source> + <translation>收款位址無效。請再檢查看看。</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>發現有重複的位址: 每個位址只能出現一次。</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2112,11 +2098,23 @@ Address: %4 <translation>刪掉這個項目</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>手續費會從要付款出去的金額中扣掉。因此收款人會收到比輸入的金額還要少的位元幣。如果有多個收款人的話,手續費會平均分配來扣除。</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>從付款金額減去手續費</translation> + </message> + <message> <source>Message:</source> <translation>訊息:</translation> </message> <message> - <source>This is a verified payment request.</source> + <source>This is an unauthenticated payment request.</source> + <translation>這是個沒驗證過的付款要求。</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> <translation>這是個已驗證的付款要求。</translation> </message> <message> @@ -2128,10 +2126,6 @@ Address: %4 <translation>附加在位元幣付款協議 URI 中的訊息,會和交易內容一起存起來,給你自己做參考。注意: 這個訊息不會送到位元幣網路上。</translation> </message> <message> - <source>This is an unverified payment request.</source> - <translation>這是個沒驗證過的付款要求。</translation> - </message> - <message> <source>Pay To:</source> <translation>付給:</translation> </message> @@ -2162,8 +2156,8 @@ Address: %4 <translation>簽署訊息</translation> </message> <message> - <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>你可以用自己的位址簽署訊息,來證明你對位址的所有權。但是請小心,不要簽署語意含糊不清的內容,因為釣魚式詐騙可能會用騙你簽署的手法來冒充是你。只有在語句中的細節你都同意時才簽署。</translation> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>你可以用自己的位址簽署訊息或合約,來證明你可以從該位址收款。但是請小心,不要簽署語意含糊不清,或隨機產生的內容,因為釣魚式詐騙可能會用騙你簽署的手法來冒充是你。只有在語句中的細節你都同意時才簽署。</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> @@ -2218,8 +2212,8 @@ Address: %4 <translation>驗證訊息</translation> </message> <message> - <source>Enter the signing 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.</source> - <translation>請在下面輸入簽署的位址,訊息(請確定完整複製了所包含的換行,空格,跳位符號等等),以及簽章,來驗證這個訊息。請小心,除了訊息內容以外,不要對簽章本身過度解讀,以避免被用「中間人攻擊法」詐騙。</translation> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>請在下面輸入收款人的位址,訊息(請確定完整複製了所包含的換行,空格,跳位符號等等),以及簽章,來驗證這個訊息。請小心,除了訊息內容以外,不要對簽章本身過度解讀,以避免被用「中間人攻擊法」詐騙。請注意,通過驗證的簽章只能證明簽章人確實可以從該位址收款,不能證明任何交易中的付款人身份!</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2485,10 +2479,6 @@ Address: %4 <translation>種類</translation> </message> <message> - <source>Address</source> - <translation>位址</translation> - </message> - <message> <source>Immature (%1 confirmations, will be available after %2)</source> <translation>未成熟(確認 %1 次,會在 %2 次後可用)</translation> </message> @@ -2517,6 +2507,10 @@ Address: %4 <translation>離線中</translation> </message> <message> + <source>Label</source> + <translation>標記</translation> + </message> + <message> <source>Unconfirmed</source> <translation>未確認</translation> </message> @@ -2573,8 +2567,8 @@ Address: %4 <translation>不論如何有一個只能觀看的地只有參與這次的交易</translation> </message> <message> - <source>Destination address of transaction.</source> - <translation>交易的目的地位址。</translation> + <source>User-defined intent/purpose of the transaction.</source> + <translation>使用者定義的交易動機或理由。</translation> </message> <message> <source>Amount removed from or added to balance.</source> @@ -2828,16 +2822,16 @@ Address: %4 <translation>這套軟體是依據 MIT 軟體授權條款散布,詳情請見附帶的 COPYING 檔案,或是以下網站: <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>進入回歸測試模式,使用可以立即解出區塊的特殊區塊鏈。</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>當錢包有交易改變時要執行的指令(指令中的 %s 會被取代成交易識別碼)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>在這個運作模式下,-genproclimit 選項控制立刻產生出的區塊數目。</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>一次錢包交易允許付出最高的總手續費;設定太低的話,可能會無法進行資料量大的交易(預設值: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. 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)</source> + <translation>修剪(刪除)掉老舊區塊來減少儲存空間的需求。這種模式會關閉錢包功能,並且和 -txindex 參數不相容。警告: 從這種模式還原會需要重新下載一整個區塊鏈。(預設值: 0 表示不修剪區塊,>%u 表示為區塊檔案的目標大小,單位是百萬位元組 MiB)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2852,6 +2846,14 @@ Address: %4 <translation>沒辦法繫結在這台電腦上的 %s 。位元幣核心可能已經在執行了。</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>警告: 收到了不尋常地多的 %d 個區塊在過去 %d 小時內生產出來(預期是 %d 個)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>警告: 請檢查你的網路連線狀況,收到了 %d 個區塊是在過去 %d 小時內生產出來(預期是 %d 個)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>警告: -paytxfee 設定了很高的金額!這可是你交易付款所要付的手續費。</translation> </message> @@ -2908,10 +2910,6 @@ Address: %4 <translation>除錯與測試選項</translation> </message> <message> - <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>找出自己的網際網路位址(預設值: 當有聽候連線且沒有 -externalip 時為 1)</translation> - </message> - <message> <source>Do not load the wallet and disable wallet RPC calls</source> <translation>不要載入錢包,並且拿掉錢包相關的 RPC 功能請求。</translation> </message> @@ -2972,8 +2970,12 @@ Address: %4 <translation>只有連接到網絡節點 <net> (IPv4,IPv6或onion)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>從目前的區塊檔 blk000??.dat 重建區塊鏈的索引</translation> + <source>Prune cannot be configured with a negative value.</source> + <translation>修剪值不能設定為負的。</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>修剪模式和 -txindex 參數不相容。</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2988,10 +2990,6 @@ Address: %4 <translation>指定錢包檔(會在資料目錄中)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>這是設計用來給回歸測試工具和應用程式開發用的。</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>正在驗證區塊資料...</translation> </message> @@ -3008,6 +3006,10 @@ Address: %4 <translation>錢包選項:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>警告: 這個版本已經被淘汰了;必須要升級!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>改變 -txindex 參數後,必須要用 -reindex 參數來重建資料庫</translation> </message> @@ -3036,14 +3038,14 @@ Address: %4 <translation>沒辦法鎖定資料目錄 %s。位元幣核心可能已經在執行了。</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> - <translation>對沒付手續費的交易持續限制每分鐘內最多只能有 <n>*1000 個位元組(預設值: %u)</translation> - </message> - <message> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation>用系統預設權限來造出新的檔案,而不是用使用者權限罩遮(umask)值 077 (只有在關掉錢包功能時才有作用)。</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>找出自己的網際網路位址(預設值: 當有聽候連線且沒有指定 -externalip 或 -proxy 時為 1)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>錯誤: 聽候外來連線失敗(回傳錯誤 %s)</translation> </message> @@ -3060,10 +3062,6 @@ Address: %4 <translation>當處理轉發的交易時,如果每千位元組(Kb)的手續費比這個值低,就視為沒付手續費 (預設值: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>當製造交易時,如果每千位元組(Kb)的手續費比這個值低,就視為沒付手續費 (預設值: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>當沒有設定 paytxfee 時,自動包含可以讓交易能在平均 n 個區塊內開始確認的手續費(預設值: %u)</translation> </message> @@ -3076,16 +3074,16 @@ Address: %4 <translation>轉發和開採時,對只帶資料的交易的大小上限(預設值: %u)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source> - <translation>一次錢包交易允許付出最高的總手續費,設定太低的話,可能會無法進行資料量大的交易(預設值: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>設定的修剪值小於最小需求的 %d MB. 請指定大一點的數字。</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>是否允許在節點位址數目不足時,使用域名查詢來搜尋節點 (預設值: 當沒用 -connect 時為 1)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default:%u)</source> - <translation>沒有手續費或手續費比較低的交易是否必須要是高優先權才會轉發(預設值: %u)</translation> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>對每個代理連線使用隨機產生的憑證。這個選項會開啟 Tor 的串流隔離(預設值: %u)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3096,6 +3094,10 @@ Address: %4 <translation>設定產生錢幣的執行緒數目(-1 表示處理器核心數,預設值: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>扣除手續費後的交易金額太少而不能傳送</translation> + </message> + <message> <source>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.</source> <translation>此產品也包含了由 OpenSSL Project 所開發的 OpenSSL Toolkit 軟體 <https://www.openssl.org/>, 和由 Eric Young 撰寫的加解密軟體,以及由 Thomas Bernard 所撰寫的 UPnP 軟體。</translation> </message> @@ -3136,14 +3138,34 @@ rpcpassword=%s <translation>在白名單中的節點不會因為偵測到阻斷服務攻擊而被停用。來自這些節點的交易也一定會被轉發,即使說交易本來就在記憶池裡了也一樣。適用於像是閘道伺服器。</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>回到非修剪的模式需要用 -reindex 參數來重建資料庫。這會導致重新下載整個區塊鏈。</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(預設值: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>接受公開的REST請求 (預設值: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>啟用最佳鏈結...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>不能在有錢包時執行修剪模式。</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>沒辦法解析 -whitebind 指定的位址: '%s'</translation> </message> <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>啓動時選擇資料目錄(預設值: 0)</translation> + </message> + <message> <source>Connect through SOCKS5 proxy</source> <translation>透過 SOCKS5 代理伺服器連線</translation> </message> @@ -3224,12 +3246,8 @@ rpcpassword=%s <translation>RPC 是否支援 HTTP 持久連線(預設值: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>隨機丟掉 <n> 分之一的網路訊息</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>隨機亂動 <n> 分之一的網路訊息裡的資料</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>啟動時從目前的區塊檔 blk000??.dat 重建區塊鏈的索引</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3240,10 +3258,22 @@ rpcpassword=%s <translation>盡可能送出不用付手續費的交易(預設值: %u)</translation> </message> <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>設定付款請求時所使用的 SSL 根憑證 (預設值: 系統憑證庫)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>設定語言,比如說 de_DE (預設值: 系統語系)</translation> + </message> + <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>顯示所有的除錯選項 (用法: --help --help-debug)</translation> </message> <message> + <source>Show splash screen on startup (default: 1)</source> + <translation>顯示啓動畫面(預設值: 1)</translation> + </message> + <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>客戶端軟體啓動時把 debug.log 檔縮小(預設值: 當沒有 -debug 時為 1)</translation> </message> @@ -3252,6 +3282,14 @@ rpcpassword=%s <translation>簽署交易失敗</translation> </message> <message> + <source>Start minimized</source> + <translation>啓動時縮到最小</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>交易金額太少而付不起手續費</translation> + </message> + <message> <source>This is experimental software.</source> <translation>這套軟體屬於實驗性質。</translation> </message> @@ -3272,6 +3310,10 @@ rpcpassword=%s <translation>交易位元量太大</translation> </message> <message> + <source>UI Options:</source> + <translation>使用介面選項:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>無法和這台電腦上的 %s 繫結(回傳錯誤 %s)</translation> </message> @@ -3292,10 +3334,6 @@ rpcpassword=%s <translation>警告</translation> </message> <message> - <source>Warning: This version is obsolete, upgrade required!</source> - <translation>警告: 這個版本已經被淘汰了,必須要升級!</translation> - </message> - <message> <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> <translation>警告: 忽略了不再支援的 -benchmark 參數,請改用 -debug=bench.</translation> </message> @@ -3356,18 +3394,10 @@ rpcpassword=%s <translation>(1 表示保留交易描述資料,像是帳戶使用者和付款請求資訊;2 表示丟掉交易描述資料)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>每當累積到 <n> 百萬位元組(MB)時,才將資料庫的變動從記憶體暫存池中寫進磁碟紀錄檔(預設值: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>使用 -checkblocks 檢查區塊的仔細程度(0 到 4,預設值: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>開採區塊的時候,紀錄交易的優先度以及每千位元組(kB)的手續費(預設值: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>維護全部交易的索引,用在 getrawtransaction 這個 RPC 請求(預設值: %u)</translation> </message> @@ -3396,18 +3426,10 @@ rpcpassword=%s <translation>是否一定要用域名查詢來搜尋節點(預設值: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>不進入安全模式,用在真的發生需要進入安全模式的事件時,強制不進入(預設值: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>載入錢包檔 wallet.dat 時發生錯誤</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>強制進入安全模式(預設值: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>生產位元幣(預設值: %u)</translation> </message> @@ -3424,10 +3446,6 @@ rpcpassword=%s <translation>無效的 -proxy 位址: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>限制簽章快取大小為 <n> 筆(預設值: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>在通訊埠 <port> 聽候 JSON-RPC 連線(預設值: %u, 或若為測試網路: %u)</translation> </message> @@ -3440,6 +3458,10 @@ rpcpassword=%s <translation>維持與節點連線數的上限為 <n> 個(預設值: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>讓錢包能公告交易</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>每個連線的接收緩衝區大小上限為 <n>*1000 個位元組(預設值: %u)</translation> </message> @@ -3448,10 +3470,6 @@ rpcpassword=%s <translation>每個連線的傳送緩衝區大小上限為 <n>*1000 個位元組(預設值: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>只接受與內建的檢查段點吻合的區塊鎖鏈(預設值: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>在除錯輸出內容前附加時間(預設值: %u)</translation> </message> @@ -3464,10 +3482,6 @@ rpcpassword=%s <translation>允許轉發非 P2SH 的多簽章交易(預設值: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>啟用定期將變動寫入錢包檔的執行緒(預設值: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>伺服器憑證檔(預設值: %s)</translation> </message> @@ -3488,10 +3502,6 @@ rpcpassword=%s <translation>設定處理 RPC 服務請求的執行緒數目(預設值: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>在錢包資料庫環境變數設定 DB_PRIVATE 旗標(預設值: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>指定設定檔(預設值: %s)</translation> </message> @@ -3508,10 +3518,6 @@ rpcpassword=%s <translation>傳送交易時可以花還沒確認的零錢(預設值: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>從磁碟匯入區塊資料後停止執行(預設值: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>與亂搞的節點斷線的臨界值 (預設: %u)</translation> </message> diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index 15a6583ca4..8bd867c103 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -30,7 +30,7 @@ public: static void cleanup(); void handleDockIconClickEvent(); -signals: +Q_SIGNALS: void dockIconClicked(); private: diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index 58a0365d3d..a41d39d51e 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -130,5 +130,5 @@ void MacDockIconHandler::handleDockIconClickEvent() this->mainWindow->show(); } - emit this->dockIconClicked(); + Q_EMIT this->dockIconClicked(); } diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index e28f903b2e..4541c75886 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -5,7 +5,6 @@ #include "networkstyle.h" #include "guiconstants.h" -#include "scicon.h" #include <QApplication> diff --git a/src/qt/notificator.h b/src/qt/notificator.h index 182e948c7d..f2a15e9c34 100644 --- a/src/qt/notificator.h +++ b/src/qt/notificator.h @@ -40,7 +40,7 @@ public: Critical /**< An error occurred */ }; -public slots: +public Q_SLOTS: /** Show notification message. @param[in] cls general message class @param[in] title title shown with message diff --git a/src/qt/openuridialog.h b/src/qt/openuridialog.h index d5c434ba9c..28b8f56ca6 100644 --- a/src/qt/openuridialog.h +++ b/src/qt/openuridialog.h @@ -21,10 +21,10 @@ public: QString getURI(); -protected slots: +protected Q_SLOTS: void accept(); -private slots: +private Q_SLOTS: void on_selectFileButton_clicked(); private: diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index a9e4b339e4..f57c1203f6 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -13,7 +13,7 @@ #include "guiutil.h" #include "optionsmodel.h" -#include "main.h" // for MAX_SCRIPTCHECK_THREADS +#include "main.h" // for DEFAULT_SCRIPTCHECK_THREADS and MAX_SCRIPTCHECK_THREADS #include "netbase.h" #include "txdb.h" // for -dbcache defaults @@ -35,14 +35,14 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : ui(new Ui::OptionsDialog), model(0), mapper(0), - fProxyIpValid(true) + fProxyIpsValid(true) { ui->setupUi(this); /* Main elements init */ ui->databaseCache->setMinimum(nMinDbCache); ui->databaseCache->setMaximum(nMaxDbCache); - ui->threadsScriptVerif->setMinimum(-(int)boost::thread::hardware_concurrency()); + ui->threadsScriptVerif->setMinimum(-GetNumCores()); ui->threadsScriptVerif->setMaximum(MAX_SCRIPTCHECK_THREADS); /* Network elements init */ @@ -54,10 +54,18 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : ui->proxyPort->setEnabled(false); ui->proxyPort->setValidator(new QIntValidator(1, 65535, this)); + ui->proxyIpTor->setEnabled(false); + ui->proxyPortTor->setEnabled(false); + ui->proxyPortTor->setValidator(new QIntValidator(1, 65535, this)); + connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool))); connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool))); + connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyIpTor, SLOT(setEnabled(bool))); + connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyPortTor, SLOT(setEnabled(bool))); + ui->proxyIp->installEventFilter(this); + ui->proxyIpTor->installEventFilter(this); /* Window elements init */ #ifdef Q_OS_MAC @@ -73,7 +81,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : /* Display elements init */ QDir translations(":translations"); ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant("")); - foreach(const QString &langStr, translations.entryList()) + Q_FOREACH(const QString &langStr, translations.entryList()) { QLocale locale(langStr); @@ -110,7 +118,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); mapper->setOrientation(Qt::Vertical); - /* setup/change UI elements when proxy IP is invalid/valid */ + /* setup/change UI elements when proxy IPs are invalid/valid */ connect(this, SIGNAL(proxyIpChecks(QValidatedLineEdit *, int)), this, SLOT(doProxyIpChecks(QValidatedLineEdit *, int))); } @@ -137,6 +145,8 @@ void OptionsDialog::setModel(OptionsModel *model) mapper->setModel(model); setMapper(); mapper->toFirst(); + + updateDefaultProxyNets(); } /* warn when one of the following settings changes by user action (placed here so init via mapper doesn't trigger them) */ @@ -149,6 +159,7 @@ void OptionsDialog::setModel(OptionsModel *model) /* Network */ connect(ui->allowIncoming, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning())); connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning())); + connect(ui->connectSocksTor, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning())); /* Display */ connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning())); connect(ui->thirdPartyTxUrls, SIGNAL(textChanged(const QString &)), this, SLOT(showRestartWarning())); @@ -173,6 +184,10 @@ void OptionsDialog::setMapper() mapper->addMapping(ui->proxyIp, OptionsModel::ProxyIP); mapper->addMapping(ui->proxyPort, OptionsModel::ProxyPort); + mapper->addMapping(ui->connectSocksTor, OptionsModel::ProxyUseTor); + mapper->addMapping(ui->proxyIpTor, OptionsModel::ProxyIPTor); + mapper->addMapping(ui->proxyPortTor, OptionsModel::ProxyPortTor); + /* Window */ #ifndef Q_OS_MAC mapper->addMapping(ui->minimizeToTray, OptionsModel::MinimizeToTray); @@ -188,7 +203,7 @@ void OptionsDialog::setMapper() void OptionsDialog::enableOkButton() { /* prevent enabling of the OK button when data modified, if there is an invalid proxy address present */ - if(fProxyIpValid) + if(fProxyIpsValid) setOkButtonState(true); } @@ -208,7 +223,7 @@ void OptionsDialog::on_resetButton_clicked() { // confirmation dialog QMessageBox::StandardButton btnRetVal = QMessageBox::question(this, tr("Confirm options reset"), - tr("Client restart required to activate changes.") + "<br><br>" + tr("Client will be shutdown, do you want to proceed?"), + tr("Client restart required to activate changes.") + "<br><br>" + tr("Client will be shut down. Do you want to proceed?"), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel); if(btnRetVal == QMessageBox::Cancel) @@ -224,6 +239,7 @@ void OptionsDialog::on_okButton_clicked() { mapper->submit(); accept(); + updateDefaultProxyNets(); } void OptionsDialog::on_cancelButton_clicked() @@ -257,11 +273,10 @@ void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPo { Q_UNUSED(nProxyPort); - const std::string strAddrProxy = pUiProxyIp->text().toStdString(); CService addrProxy; /* Check for a valid IPv4 / IPv6 address */ - if (!(fProxyIpValid = LookupNumeric(strAddrProxy.c_str(), addrProxy))) + if (!(fProxyIpsValid = LookupNumeric(pUiProxyIp->text().toStdString().c_str(), addrProxy))) { disableOkButton(); pUiProxyIp->setValid(false); @@ -275,13 +290,39 @@ void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPo } } +void OptionsDialog::updateDefaultProxyNets() +{ + proxyType proxy; + std::string strProxy; + QString strDefaultProxyGUI; + + GetProxy(NET_IPV4, proxy); + strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort(); + strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text(); + (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachIPv4->setChecked(true) : ui->proxyReachIPv4->setChecked(false); + + GetProxy(NET_IPV6, proxy); + strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort(); + strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text(); + (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachIPv6->setChecked(true) : ui->proxyReachIPv6->setChecked(false); + + GetProxy(NET_TOR, proxy); + strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort(); + strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text(); + (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachTor->setChecked(true) : ui->proxyReachTor->setChecked(false); +} + bool OptionsDialog::eventFilter(QObject *object, QEvent *event) { if(event->type() == QEvent::FocusOut) { if(object == ui->proxyIp) { - emit proxyIpChecks(ui->proxyIp, ui->proxyPort->text().toInt()); + Q_EMIT proxyIpChecks(ui->proxyIp, ui->proxyPort->text().toInt()); + } + else if(object == ui->proxyIpTor) + { + Q_EMIT proxyIpChecks(ui->proxyIpTor, ui->proxyPortTor->text().toInt()); } } return QDialog::eventFilter(object, event); diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index f4e5157595..348489c599 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -33,7 +33,7 @@ public: protected: bool eventFilter(QObject *object, QEvent *event); -private slots: +private Q_SLOTS: /* enable OK button */ void enableOkButton(); /* disable OK button */ @@ -47,15 +47,17 @@ private slots: void showRestartWarning(bool fPersistent = false); void clearStatusLabel(); void doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort); + /* query the networks, for which the default proxy is used */ + void updateDefaultProxyNets(); -signals: +Q_SIGNALS: void proxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort); private: Ui::OptionsDialog *ui; OptionsModel *model; QDataWidgetMapper *mapper; - bool fProxyIpValid; + bool fProxyIpsValid; }; #endif // BITCOIN_QT_OPTIONSDIALOG_H diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 41d6acf358..65e490570e 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -13,7 +13,7 @@ #include "amount.h" #include "init.h" -#include "main.h" +#include "main.h" // For DEFAULT_SCRIPTCHECK_THREADS #include "net.h" #include "txdb.h" // for -dbcache defaults @@ -117,6 +117,16 @@ void OptionsModel::Init() else if(!settings.value("fUseProxy").toBool() && !GetArg("-proxy", "").empty()) addOverriddenOption("-proxy"); + if (!settings.contains("fUseSeparateProxyTor")) + settings.setValue("fUseSeparateProxyTor", false); + if (!settings.contains("addrSeparateProxyTor")) + settings.setValue("addrSeparateProxyTor", "127.0.0.1:9050"); + // Only try to set -onion, if user has enabled fUseSeparateProxyTor + if (settings.value("fUseSeparateProxyTor").toBool() && !SoftSetArg("-onion", settings.value("addrSeparateProxyTor").toString().toStdString())) + addOverriddenOption("-onion"); + else if(!settings.value("fUseSeparateProxyTor").toBool() && !GetArg("-onion", "").empty()) + addOverriddenOption("-onion"); + // Display if (!settings.contains("language")) settings.setValue("language", ""); @@ -178,6 +188,20 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const return strlIpPort.at(1); } + // separate Tor proxy + case ProxyUseTor: + return settings.value("fUseSeparateProxyTor", false); + case ProxyIPTor: { + // contains IP at index 0 and port at index 1 + QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts); + return strlIpPort.at(0); + } + case ProxyPortTor: { + // contains IP at index 0 and port at index 1 + QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts); + return strlIpPort.at(1); + } + #ifdef ENABLE_WALLET case SpendZeroConfChange: return settings.value("bSpendZeroConfChange"); @@ -259,6 +283,39 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in } } break; + + // separate Tor proxy + case ProxyUseTor: + if (settings.value("fUseSeparateProxyTor") != value) { + settings.setValue("fUseSeparateProxyTor", value.toBool()); + setRestartRequired(true); + } + break; + case ProxyIPTor: { + // contains current IP at index 0 and current port at index 1 + QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts); + // if that key doesn't exist or has a changed IP + if (!settings.contains("addrSeparateProxyTor") || strlIpPort.at(0) != value.toString()) { + // construct new value from new IP and current port + QString strNewValue = value.toString() + ":" + strlIpPort.at(1); + settings.setValue("addrSeparateProxyTor", strNewValue); + setRestartRequired(true); + } + } + break; + case ProxyPortTor: { + // contains current IP at index 0 and current port at index 1 + QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts); + // if that key doesn't exist or has a changed port + if (!settings.contains("addrSeparateProxyTor") || strlIpPort.at(1) != value.toString()) { + // construct new value from current IP and new port + QString strNewValue = strlIpPort.at(0) + ":" + value.toString(); + settings.setValue("addrSeparateProxyTor", strNewValue); + setRestartRequired(true); + } + } + break; + #ifdef ENABLE_WALLET case SpendZeroConfChange: if (settings.value("bSpendZeroConfChange") != value) { @@ -286,7 +343,7 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in case CoinControlFeatures: fCoinControlFeatures = value.toBool(); settings.setValue("fCoinControlFeatures", fCoinControlFeatures); - emit coinControlFeaturesChanged(fCoinControlFeatures); + Q_EMIT coinControlFeaturesChanged(fCoinControlFeatures); break; case DatabaseCache: if (settings.value("nDatabaseCache") != value) { @@ -311,7 +368,7 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in } } - emit dataChanged(index, index); + Q_EMIT dataChanged(index, index); return successful; } @@ -324,7 +381,7 @@ void OptionsModel::setDisplayUnit(const QVariant &value) QSettings settings; nDisplayUnit = value.toInt(); settings.setValue("nDisplayUnit", nDisplayUnit); - emit displayUnitChanged(nDisplayUnit); + Q_EMIT displayUnitChanged(nDisplayUnit); } } diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index bf892768ed..8448cad8de 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -34,6 +34,9 @@ public: ProxyUse, // bool ProxyIP, // QString ProxyPort, // int + ProxyUseTor, // bool + ProxyIPTor, // QString + ProxyPortTor, // int DisplayUnit, // BitcoinUnits::Unit ThirdPartyTxUrls, // QString Language, // QString @@ -81,7 +84,7 @@ private: /// Add option to list of GUI options overridden through command line/config file void addOverriddenOption(const std::string &option); -signals: +Q_SIGNALS: void displayUnitChanged(int unit); void coinControlFeaturesChanged(bool); }; diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 4fa15db9c6..a56c80ac63 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -10,7 +10,7 @@ #include "guiconstants.h" #include "guiutil.h" #include "optionsmodel.h" -#include "scicon.h" +#include "platformstyle.h" #include "transactionfilterproxy.h" #include "transactiontablemodel.h" #include "walletmodel.h" @@ -18,14 +18,16 @@ #include <QAbstractItemDelegate> #include <QPainter> -#define DECORATION_SIZE 64 -#define NUM_ITEMS 3 +#define DECORATION_SIZE 54 +#define NUM_ITEMS 5 class TxViewDelegate : public QAbstractItemDelegate { Q_OBJECT public: - TxViewDelegate(): QAbstractItemDelegate(), unit(BitcoinUnits::BTC) + TxViewDelegate(const PlatformStyle *platformStyle): + QAbstractItemDelegate(), unit(BitcoinUnits::BTC), + platformStyle(platformStyle) { } @@ -43,7 +45,7 @@ public: int halfheight = (mainRect.height() - 2*ypad)/2; QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight); QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight); - icon = SingleColorIcon(icon, SingleColor()); + icon = platformStyle->SingleColorIcon(icon); icon.paint(painter, decorationRect); QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime(); @@ -101,11 +103,12 @@ public: } int unit; + const PlatformStyle *platformStyle; }; #include "overviewpage.moc" -OverviewPage::OverviewPage(QWidget *parent) : +OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) : QWidget(parent), ui(new Ui::OverviewPage), clientModel(0), @@ -116,11 +119,17 @@ OverviewPage::OverviewPage(QWidget *parent) : currentWatchOnlyBalance(-1), currentWatchUnconfBalance(-1), currentWatchImmatureBalance(-1), - txdelegate(new TxViewDelegate()), + txdelegate(new TxViewDelegate(platformStyle)), filter(0) { ui->setupUi(this); + // use a SingleColorIcon for the "out of sync warning" icon + QIcon icon = platformStyle->SingleColorIcon(":/icons/warning"); + icon.addPixmap(icon.pixmap(QSize(64,64), QIcon::Normal), QIcon::Disabled); // also set the disabled icon because we are using a disabled QPushButton to work around missing HiDPI support of QLabel (https://bugreports.qt.io/browse/QTBUG-42503) + ui->labelTransactionsStatus->setIcon(icon); + ui->labelWalletStatus->setIcon(icon); + // Recent transactions ui->listTransactions->setItemDelegate(txdelegate); ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE)); @@ -129,10 +138,6 @@ OverviewPage::OverviewPage(QWidget *parent) : connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SLOT(handleTransactionClicked(QModelIndex))); - // init "out of sync" warning labels - ui->labelWalletStatus->setText("(" + tr("out of sync") + ")"); - ui->labelTransactionsStatus->setText("(" + tr("out of sync") + ")"); - // start with displaying the "out of sync" warnings showOutOfSyncWarning(true); } @@ -140,7 +145,7 @@ OverviewPage::OverviewPage(QWidget *parent) : void OverviewPage::handleTransactionClicked(const QModelIndex &index) { if(filter) - emit transactionClicked(filter->mapToSource(index)); + Q_EMIT transactionClicked(filter->mapToSource(index)); } OverviewPage::~OverviewPage() diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 64cb1dc4e0..4139eb35d3 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -12,6 +12,7 @@ class ClientModel; class TransactionFilterProxy; class TxViewDelegate; +class PlatformStyle; class WalletModel; namespace Ui { @@ -28,18 +29,18 @@ class OverviewPage : public QWidget Q_OBJECT public: - explicit OverviewPage(QWidget *parent = 0); + explicit OverviewPage(const PlatformStyle *platformStyle, QWidget *parent = 0); ~OverviewPage(); void setClientModel(ClientModel *clientModel); void setWalletModel(WalletModel *walletModel); void showOutOfSyncWarning(bool fShow); -public slots: +public Q_SLOTS: void setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance); -signals: +Q_SIGNALS: void transactionClicked(const QModelIndex &index); private: @@ -56,7 +57,7 @@ private: TxViewDelegate *txdelegate; TransactionFilterProxy *filter; -private slots: +private Q_SLOTS: void updateDisplayUnit(); void handleTransactionClicked(const QModelIndex &index); void updateAlerts(const QString &warnings); diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 7e9729eeb9..78a783dea4 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -19,8 +19,6 @@ #include <QDebug> #include <QSslCertificate> -using namespace std; - class SSLVerifyError : public std::runtime_error { public: @@ -49,7 +47,7 @@ bool PaymentRequestPlus::parse(const QByteArray& data) return true; } -bool PaymentRequestPlus::SerializeToString(string* output) const +bool PaymentRequestPlus::SerializeToString(std::string* output) const { return paymentRequest.SerializeToString(output); } diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 09e9949b10..31a6d65a8d 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -10,7 +10,7 @@ #include "base58.h" #include "chainparams.h" -#include "main.h" +#include "main.h" // For minRelayTxFee #include "ui_interface.h" #include "util.h" #include "wallet/wallet.h" @@ -46,8 +46,6 @@ #include <QUrlQuery> #endif -using namespace std; - const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds const QString BITCOIN_IPC_PREFIX("bitcoin:"); // BIP70 payment protocol messages @@ -148,7 +146,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) int nRootCerts = 0; const QDateTime currentTime = QDateTime::currentDateTime(); - foreach (const QSslCertificate& cert, certList) { + Q_FOREACH (const QSslCertificate& cert, certList) { // Don't log NULL certificates if (cert.isNull()) continue; @@ -201,7 +199,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) // when uiReady() is called. // // Warning: ipcSendCommandLine() is called early in init, -// so don't use "emit message()", but "QMessageBox::"! +// so don't use "Q_EMIT message()", but "QMessageBox::"! // void PaymentServer::ipcParseCommandLine(int argc, char* argv[]) { @@ -269,7 +267,7 @@ void PaymentServer::ipcParseCommandLine(int argc, char* argv[]) bool PaymentServer::ipcSendCommandLine() { bool fResult = false; - foreach (const QString& r, savedPaymentRequests) + Q_FOREACH (const QString& r, savedPaymentRequests) { QLocalSocket* socket = new QLocalSocket(); socket->connectToServer(ipcServerName(), QIODevice::WriteOnly); @@ -326,7 +324,7 @@ PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) : uriServer = new QLocalServer(this); if (!uriServer->listen(name)) { - // constructor is called early in init, so don't use "emit message()" here + // constructor is called early in init, so don't use "Q_EMIT message()" here QMessageBox::critical(0, tr("Payment request error"), tr("Cannot start bitcoin: click-to-pay handler")); } @@ -394,7 +392,7 @@ void PaymentServer::uiReady() initNetManager(); saveURIs = false; - foreach (const QString& s, savedPaymentRequests) + Q_FOREACH (const QString& s, savedPaymentRequests) { handleURIOrFile(s); } @@ -431,7 +429,7 @@ void PaymentServer::handleURIOrFile(const QString& s) else { qWarning() << "PaymentServer::handleURIOrFile: Invalid URL: " << fetchUrl; - emit message(tr("URI handling"), + Q_EMIT message(tr("URI handling"), tr("Payment request fetch URL is invalid: %1").arg(fetchUrl.toString()), CClientUIInterface::ICON_WARNING); } @@ -445,14 +443,14 @@ void PaymentServer::handleURIOrFile(const QString& s) { CBitcoinAddress address(recipient.address.toStdString()); if (!address.IsValid()) { - emit message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address), + Q_EMIT message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address), CClientUIInterface::MSG_ERROR); } else - emit receivedPaymentRequest(recipient); + Q_EMIT receivedPaymentRequest(recipient); } else - emit message(tr("URI handling"), + Q_EMIT message(tr("URI handling"), tr("URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."), CClientUIInterface::ICON_WARNING); @@ -466,12 +464,12 @@ void PaymentServer::handleURIOrFile(const QString& s) SendCoinsRecipient recipient; if (!readPaymentRequestFromFile(s, request)) { - emit message(tr("Payment request file handling"), + Q_EMIT message(tr("Payment request file handling"), tr("Payment request file cannot be read! This can be caused by an invalid payment request file."), CClientUIInterface::ICON_WARNING); } else if (processPaymentRequest(request, recipient)) - emit receivedPaymentRequest(recipient); + Q_EMIT receivedPaymentRequest(recipient); return; } @@ -500,7 +498,7 @@ void PaymentServer::handleURIConnection() // // Warning: readPaymentRequestFromFile() is used in ipcSendCommandLine() -// so don't use "emit message()", but "QMessageBox::"! +// so don't use "Q_EMIT message()", but "QMessageBox::"! // bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request) { @@ -511,12 +509,7 @@ bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentR } // BIP70 DoS protection - if (f.size() > BIP70_MAX_PAYMENTREQUEST_SIZE) { - qWarning() << QString("PaymentServer::%1: Payment request %2 is too large (%3 bytes, allowed %4 bytes).") - .arg(__func__) - .arg(filename) - .arg(f.size()) - .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); + if (!verifySize(f.size())) { return false; } @@ -533,7 +526,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen if (request.IsInitialized()) { // Payment request network matches client network? if (!verifyNetwork(request.getDetails())) { - emit message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."), + Q_EMIT message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."), CClientUIInterface::MSG_ERROR); return false; @@ -542,13 +535,13 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen // Make sure any payment requests involved are still valid. // This is re-checked just before sending coins in WalletModel::sendCoins(). if (verifyExpired(request.getDetails())) { - emit message(tr("Payment request rejected"), tr("Payment request expired."), + Q_EMIT message(tr("Payment request rejected"), tr("Payment request expired."), CClientUIInterface::MSG_ERROR); return false; } } else { - emit message(tr("Payment request error"), tr("Payment request is not initialized."), + Q_EMIT message(tr("Payment request error"), tr("Payment request is not initialized."), CClientUIInterface::MSG_ERROR); return false; @@ -562,7 +555,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen QList<std::pair<CScript, CAmount> > sendingTos = request.getPayTo(); QStringList addresses; - foreach(const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) { + Q_FOREACH(const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) { // Extract and check destination addresses CTxDestination dest; if (ExtractDestination(sendingTo.first, dest)) { @@ -573,7 +566,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen // Unauthenticated payment requests to custom bitcoin addresses are not supported // (there is no good way to tell the user where they are paying in a way they'd // have a chance of understanding). - emit message(tr("Payment request rejected"), + Q_EMIT message(tr("Payment request rejected"), tr("Unverified payment requests to custom payment scripts are unsupported."), CClientUIInterface::MSG_ERROR); return false; @@ -583,14 +576,14 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen // but CAmount is defined as int64_t. Because of that we need to verify that amounts are in a valid range // and no overflow has happened. if (!verifyAmount(sendingTo.second)) { - emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR); + Q_EMIT message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR); return false; } // Extract and check amounts CTxOut txOut(sendingTo.second, sendingTo.first); if (txOut.IsDust(::minRelayTxFee)) { - emit message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).") + Q_EMIT message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).") .arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second)), CClientUIInterface::MSG_ERROR); @@ -600,7 +593,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen recipient.amount += sendingTo.second; // Also verify that the final amount is still in a valid range after adding additional amounts. if (!verifyAmount(recipient.amount)) { - emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR); + Q_EMIT message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR); return false; } } @@ -647,7 +640,7 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien // Create a new refund address, or re-use: QString account = tr("Refund from %1").arg(recipient.authenticatedMerchant); std::string strAccount = account.toStdString(); - set<CTxDestination> refundAddresses = wallet->GetAccountAddresses(strAccount); + std::set<CTxDestination> refundAddresses = wallet->GetAccountAddresses(strAccount); if (!refundAddresses.empty()) { CScript s = GetScriptForDestination(*refundAddresses.begin()); payments::Output* refund_to = payment.add_refund_to(); @@ -687,14 +680,13 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) reply->deleteLater(); // BIP70 DoS protection - if (reply->size() > BIP70_MAX_PAYMENTREQUEST_SIZE) { - QString msg = tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).") - .arg(reply->request().url().toString()) - .arg(reply->size()) - .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); - - qWarning() << QString("PaymentServer::%1:").arg(__func__) << msg; - emit message(tr("Payment request DoS protection"), msg, CClientUIInterface::MSG_ERROR); + if (!verifySize(reply->size())) { + Q_EMIT message(tr("Payment request rejected"), + tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).") + .arg(reply->request().url().toString()) + .arg(reply->size()) + .arg(BIP70_MAX_PAYMENTREQUEST_SIZE), + CClientUIInterface::MSG_ERROR); return; } @@ -704,7 +696,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) .arg(reply->errorString()); qWarning() << "PaymentServer::netRequestFinished: " << msg; - emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); + Q_EMIT message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); return; } @@ -718,12 +710,12 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) if (!request.parse(data)) { qWarning() << "PaymentServer::netRequestFinished: Error parsing payment request"; - emit message(tr("Payment request error"), + Q_EMIT message(tr("Payment request error"), tr("Payment request cannot be parsed!"), CClientUIInterface::MSG_ERROR); } else if (processPaymentRequest(request, recipient)) - emit receivedPaymentRequest(recipient); + Q_EMIT receivedPaymentRequest(recipient); return; } @@ -736,11 +728,11 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) .arg(reply->request().url().toString()); qWarning() << "PaymentServer::netRequestFinished: " << msg; - emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); + Q_EMIT message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); } else { - emit receivedPaymentACK(GUIUtil::HtmlEscape(paymentACK.memo())); + Q_EMIT receivedPaymentACK(GUIUtil::HtmlEscape(paymentACK.memo())); } } } @@ -750,11 +742,11 @@ void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList<QSslError> Q_UNUSED(reply); QString errString; - foreach (const QSslError& err, errs) { + Q_FOREACH (const QSslError& err, errs) { qWarning() << "PaymentServer::reportSslErrors: " << err; errString += err.errorString() + "\n"; } - emit message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR); + Q_EMIT message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR); } void PaymentServer::setOptionsModel(OptionsModel *optionsModel) @@ -764,8 +756,8 @@ void PaymentServer::setOptionsModel(OptionsModel *optionsModel) void PaymentServer::handlePaymentACK(const QString& paymentACKMsg) { - // currently we don't futher process or store the paymentACK message - emit message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL); + // currently we don't further process or store the paymentACK message + Q_EMIT message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL); } bool PaymentServer::verifyNetwork(const payments::PaymentDetails& requestDetails) @@ -792,6 +784,18 @@ bool PaymentServer::verifyExpired(const payments::PaymentDetails& requestDetails return fVerified; } +bool PaymentServer::verifySize(qint64 requestSize) +{ + bool fVerified = (requestSize <= BIP70_MAX_PAYMENTREQUEST_SIZE); + if (!fVerified) { + qWarning() << QString("PaymentServer::%1: Payment request too large (%2 bytes, allowed %3 bytes).") + .arg(__func__) + .arg(requestSize) + .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); + } + return fVerified; +} + bool PaymentServer::verifyAmount(const CAmount& requestAmount) { bool fVerified = MoneyRange(requestAmount); diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 32ed27983e..fa120a435c 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -88,17 +88,16 @@ public: // OptionsModel is used for getting proxy settings and display unit void setOptionsModel(OptionsModel *optionsModel); - // This is now public, because we use it in paymentservertests.cpp - static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request); - // Verify that the payment request network matches the client network static bool verifyNetwork(const payments::PaymentDetails& requestDetails); // Verify if the payment request is expired static bool verifyExpired(const payments::PaymentDetails& requestDetails); + // Verify the payment request size is valid as per BIP70 + static bool verifySize(qint64 requestSize); // Verify the payment request amount is valid static bool verifyAmount(const CAmount& requestAmount); -signals: +Q_SIGNALS: // Fired when a valid payment request is received void receivedPaymentRequest(SendCoinsRecipient); @@ -108,7 +107,7 @@ signals: // Fired when a message should be reported to the user void message(const QString &title, const QString &message, unsigned int style); -public slots: +public Q_SLOTS: // Signal this when the main window's UI is ready // to display payment requests to the user void uiReady(); @@ -119,7 +118,7 @@ public slots: // Handle an incoming URI, URI with local file scheme or file void handleURIOrFile(const QString& s); -private slots: +private Q_SLOTS: void handleURIConnection(); void netRequestFinished(QNetworkReply*); void reportSslErrors(QNetworkReply*, const QList<QSslError> &); @@ -131,6 +130,7 @@ protected: bool eventFilter(QObject *object, QEvent *event); private: + static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request); bool processPaymentRequest(const PaymentRequestPlus& request, SendCoinsRecipient& recipient); void fetchRequest(const QUrl& url); diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 220f273d02..770a860544 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -8,7 +8,6 @@ #include "guiconstants.h" #include "guiutil.h" -#include "net.h" #include "sync.h" #include <QDebug> @@ -63,11 +62,12 @@ public: #if QT_VERSION >= 0x040700 cachedNodeStats.reserve(vNodes.size()); #endif - BOOST_FOREACH(CNode* pnode, vNodes) + Q_FOREACH (CNode* pnode, vNodes) { CNodeCombinedStats stats; stats.nodeStateStats.nMisbehavior = 0; stats.nodeStateStats.nSyncHeight = -1; + stats.nodeStateStats.nCommonHeight = -1; stats.fNodeStateStatsAvailable = false; pnode->copyStats(stats.nodeStats); cachedNodeStats.append(stats); @@ -91,22 +91,21 @@ public: // build index map mapNodeRows.clear(); int row = 0; - BOOST_FOREACH(CNodeCombinedStats &stats, cachedNodeStats) + Q_FOREACH (const CNodeCombinedStats& stats, cachedNodeStats) mapNodeRows.insert(std::pair<NodeId, int>(stats.nodeStats.nodeid, row++)); } - int size() + int size() const { return cachedNodeStats.size(); } CNodeCombinedStats *index(int idx) { - if(idx >= 0 && idx < cachedNodeStats.size()) { + if (idx >= 0 && idx < cachedNodeStats.size()) return &cachedNodeStats[idx]; - } else { - return 0; - } + + return 0; } }; @@ -170,7 +169,7 @@ QVariant PeerTableModel::data(const QModelIndex &index, int role) const } } else if (role == Qt::TextAlignmentRole) { if (index.column() == Ping) - return (int)(Qt::AlignRight | Qt::AlignVCenter); + return (QVariant)(Qt::AlignRight | Qt::AlignVCenter); } return QVariant(); @@ -203,13 +202,8 @@ QModelIndex PeerTableModel::index(int row, int column, const QModelIndex &parent CNodeCombinedStats *data = priv->index(row); if (data) - { return createIndex(row, column, data); - } - else - { - return QModelIndex(); - } + return QModelIndex(); } const CNodeCombinedStats *PeerTableModel::getNodeStats(int idx) @@ -219,9 +213,9 @@ const CNodeCombinedStats *PeerTableModel::getNodeStats(int idx) void PeerTableModel::refresh() { - emit layoutAboutToBeChanged(); + Q_EMIT layoutAboutToBeChanged(); priv->refreshPeers(); - emit layoutChanged(); + Q_EMIT layoutChanged(); } int PeerTableModel::getRowByNodeId(NodeId nodeid) diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h index bff7bb824e..5f149ea873 100644 --- a/src/qt/peertablemodel.h +++ b/src/qt/peertablemodel.h @@ -5,7 +5,7 @@ #ifndef BITCOIN_QT_PEERTABLEMODEL_H #define BITCOIN_QT_PEERTABLEMODEL_H -#include "main.h" +#include "main.h" // For CNodeStateStats #include "net.h" #include <QAbstractTableModel> @@ -68,7 +68,7 @@ public: void sort(int column, Qt::SortOrder order); /*@}*/ -public slots: +public Q_SLOTS: void refresh(); private: diff --git a/src/qt/platformstyle.cpp b/src/qt/platformstyle.cpp new file mode 100644 index 0000000000..11cbc7a47c --- /dev/null +++ b/src/qt/platformstyle.cpp @@ -0,0 +1,147 @@ +// 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 "platformstyle.h" + +#include "guiconstants.h" + +#include <QApplication> +#include <QColor> +#include <QIcon> +#include <QImage> +#include <QPalette> +#include <QPixmap> + +static const struct { + const char *platformId; + /** Show images on push buttons */ + const bool imagesOnButtons; + /** Colorize single-color icons */ + const bool colorizeIcons; + /** Extra padding/spacing in transactionview */ + const bool useExtraSpacing; +} platform_styles[] = { + {"macosx", false, false, true}, + {"windows", true, false, false}, + /* Other: linux, unix, ... */ + {"other", true, true, false} +}; +static const unsigned platform_styles_count = sizeof(platform_styles)/sizeof(*platform_styles); + +namespace { +/* Local functions for colorizing single-color images */ + +void MakeSingleColorImage(QImage& img, const QColor& colorbase) +{ + img = img.convertToFormat(QImage::Format_ARGB32); + for (int x = img.width(); x--; ) + { + for (int y = img.height(); y--; ) + { + const QRgb rgb = img.pixel(x, y); + img.setPixel(x, y, qRgba(colorbase.red(), colorbase.green(), colorbase.blue(), qAlpha(rgb))); + } + } +} + +QIcon ColorizeIcon(const QIcon& ico, const QColor& colorbase) +{ + QIcon new_ico; + QSize sz; + Q_FOREACH(sz, ico.availableSizes()) + { + QImage img(ico.pixmap(sz).toImage()); + MakeSingleColorImage(img, colorbase); + new_ico.addPixmap(QPixmap::fromImage(img)); + } + return new_ico; +} + +QImage ColorizeImage(const QString& filename, const QColor& colorbase) +{ + QImage img(filename); + MakeSingleColorImage(img, colorbase); + return img; +} + +QIcon ColorizeIcon(const QString& filename, const QColor& colorbase) +{ + return QIcon(QPixmap::fromImage(ColorizeImage(filename, colorbase))); +} + +} + + +PlatformStyle::PlatformStyle(const QString &name, bool imagesOnButtons, bool colorizeIcons, bool useExtraSpacing): + name(name), + imagesOnButtons(imagesOnButtons), + colorizeIcons(colorizeIcons), + useExtraSpacing(useExtraSpacing), + singleColor(0,0,0), + textColor(0,0,0) +{ + // Determine icon highlighting color + if (colorizeIcons) { + const QColor colorHighlightBg(QApplication::palette().color(QPalette::Highlight)); + const QColor colorHighlightFg(QApplication::palette().color(QPalette::HighlightedText)); + const QColor colorText(QApplication::palette().color(QPalette::WindowText)); + const int colorTextLightness = colorText.lightness(); + QColor colorbase; + if (abs(colorHighlightBg.lightness() - colorTextLightness) < abs(colorHighlightFg.lightness() - colorTextLightness)) + colorbase = colorHighlightBg; + else + colorbase = colorHighlightFg; + singleColor = colorbase; + } + // Determine text color + textColor = QColor(QApplication::palette().color(QPalette::WindowText)); +} + +QImage PlatformStyle::SingleColorImage(const QString& filename) const +{ + if (!colorizeIcons) + return QImage(filename); + return ColorizeImage(filename, SingleColor()); +} + +QIcon PlatformStyle::SingleColorIcon(const QString& filename) const +{ + if (!colorizeIcons) + return QIcon(filename); + return ColorizeIcon(filename, SingleColor()); +} + +QIcon PlatformStyle::SingleColorIcon(const QIcon& icon) const +{ + if (!colorizeIcons) + return icon; + return ColorizeIcon(icon, SingleColor()); +} + +QIcon PlatformStyle::TextColorIcon(const QString& filename) const +{ + return ColorizeIcon(filename, TextColor()); +} + +QIcon PlatformStyle::TextColorIcon(const QIcon& icon) const +{ + return ColorizeIcon(icon, TextColor()); +} + +const PlatformStyle *PlatformStyle::instantiate(const QString &platformId) +{ + for (unsigned x=0; x<platform_styles_count; ++x) + { + if (platformId == platform_styles[x].platformId) + { + return new PlatformStyle( + platform_styles[x].platformId, + platform_styles[x].imagesOnButtons, + platform_styles[x].colorizeIcons, + platform_styles[x].useExtraSpacing); + } + } + return 0; +} + diff --git a/src/qt/platformstyle.h b/src/qt/platformstyle.h new file mode 100644 index 0000000000..4e763e760e --- /dev/null +++ b/src/qt/platformstyle.h @@ -0,0 +1,55 @@ +// 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_QT_PLATFORMSTYLE_H +#define BITCOIN_QT_PLATFORMSTYLE_H + +#include <QIcon> +#include <QPixmap> +#include <QString> + +/* Coin network-specific GUI style information */ +class PlatformStyle +{ +public: + /** Get style associated with provided platform name, or 0 if not known */ + static const PlatformStyle *instantiate(const QString &platformId); + + const QString &getName() const { return name; } + + bool getImagesOnButtons() const { return imagesOnButtons; } + bool getUseExtraSpacing() const { return useExtraSpacing; } + + QColor TextColor() const { return textColor; } + QColor SingleColor() const { return singleColor; } + + /** Colorize an image (given filename) with the icon color */ + QImage SingleColorImage(const QString& filename) const; + + /** Colorize an icon (given filename) with the icon color */ + QIcon SingleColorIcon(const QString& filename) const; + + /** Colorize an icon (given object) with the icon color */ + QIcon SingleColorIcon(const QIcon& icon) const; + + /** Colorize an icon (given filename) with the text color */ + QIcon TextColorIcon(const QString& filename) const; + + /** Colorize an icon (given object) with the text color */ + QIcon TextColorIcon(const QIcon& icon) const; + +private: + PlatformStyle(const QString &name, bool imagesOnButtons, bool colorizeIcons, bool useExtraSpacing); + + QString name; + bool imagesOnButtons; + bool colorizeIcons; + bool useExtraSpacing; + QColor singleColor; + QColor textColor; + /* ... more to come later */ +}; + +#endif // BITCOIN_QT_PLATFORMSTYLE_H + diff --git a/src/qt/qvalidatedlineedit.h b/src/qt/qvalidatedlineedit.h index f63568d27f..8665acda5e 100644 --- a/src/qt/qvalidatedlineedit.h +++ b/src/qt/qvalidatedlineedit.h @@ -27,11 +27,11 @@ private: bool valid; const QValidator *checkValidator; -public slots: +public Q_SLOTS: void setValid(bool valid); void setEnabled(bool enabled); -private slots: +private Q_SLOTS: void markValid(); void checkValidity(); }; diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp index f73268c958..800436661f 100644 --- a/src/qt/qvaluecombobox.cpp +++ b/src/qt/qvaluecombobox.cpp @@ -27,5 +27,5 @@ void QValueComboBox::setRole(int role) void QValueComboBox::handleSelectionChanged(int idx) { - emit valueChanged(); + Q_EMIT valueChanged(); } diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h index dc85d64cb5..5b20e6a5a4 100644 --- a/src/qt/qvaluecombobox.h +++ b/src/qt/qvaluecombobox.h @@ -24,13 +24,13 @@ public: /** Specify model role to use as ordinal value (defaults to Qt::UserRole) */ void setRole(int role); -signals: +Q_SIGNALS: void valueChanged(); private: int role; -private slots: +private Q_SLOTS: void handleSelectionChanged(int idx); }; diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 28cbd3abed..7fb68cc32a 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -10,9 +10,9 @@ #include "bitcoinunits.h" #include "guiutil.h" #include "optionsmodel.h" +#include "platformstyle.h" #include "receiverequestdialog.h" #include "recentrequeststablemodel.h" -#include "scicon.h" #include "walletmodel.h" #include <QAction> @@ -22,24 +22,25 @@ #include <QScrollBar> #include <QTextDocument> -ReceiveCoinsDialog::ReceiveCoinsDialog(QWidget *parent) : +ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::ReceiveCoinsDialog), - model(0) + model(0), + platformStyle(platformStyle) { ui->setupUi(this); -#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac - ui->clearButton->setIcon(QIcon()); - ui->receiveButton->setIcon(QIcon()); - ui->showRequestButton->setIcon(QIcon()); - ui->removeRequestButton->setIcon(QIcon()); -#else - ui->clearButton->setIcon(SingleColorIcon(":/icons/remove")); - ui->receiveButton->setIcon(SingleColorIcon(":/icons/receiving_addresses")); - ui->showRequestButton->setIcon(SingleColorIcon(":/icons/edit")); - ui->removeRequestButton->setIcon(SingleColorIcon(":/icons/remove")); -#endif + if (!platformStyle->getImagesOnButtons()) { + ui->clearButton->setIcon(QIcon()); + ui->receiveButton->setIcon(QIcon()); + ui->showRequestButton->setIcon(QIcon()); + ui->removeRequestButton->setIcon(QIcon()); + } else { + ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + ui->receiveButton->setIcon(platformStyle->SingleColorIcon(":/icons/receiving_addresses")); + ui->showRequestButton->setIcon(platformStyle->SingleColorIcon(":/icons/edit")); + ui->removeRequestButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + } // context menu actions QAction *copyLabelAction = new QAction(tr("Copy label"), this); @@ -132,7 +133,7 @@ void ReceiveCoinsDialog::on_receiveButton_clicked() if(ui->reuseAddress->isChecked()) { /* Choose existing receiving address */ - AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this); + AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this); dlg.setModel(model->getAddressTableModel()); if(dlg.exec()) { @@ -185,8 +186,7 @@ void ReceiveCoinsDialog::on_showRequestButton_clicked() return; QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows(); - foreach (QModelIndex index, selection) - { + Q_FOREACH (const QModelIndex& index, selection) { on_recentRequestsView_doubleClicked(index); } } diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index 70a1842fa2..eaaf129a91 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -16,6 +16,7 @@ #include <QVariant> class OptionsModel; +class PlatformStyle; class WalletModel; namespace Ui { @@ -39,12 +40,12 @@ public: MINIMUM_COLUMN_WIDTH = 130 }; - explicit ReceiveCoinsDialog(QWidget *parent = 0); + explicit ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent = 0); ~ReceiveCoinsDialog(); void setModel(WalletModel *model); -public slots: +public Q_SLOTS: void clear(); void reject(); void accept(); @@ -57,10 +58,12 @@ private: GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer; WalletModel *model; QMenu *contextMenu; + const PlatformStyle *platformStyle; + void copyColumnToClipboard(int column); virtual void resizeEvent(QResizeEvent *event); -private slots: +private Q_SLOTS: void on_receiveButton_clicked(); void on_showRequestButton_clicked(); void on_removeRequestButton_clicked(); diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index 3e5f897be6..69f84ebbd7 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -32,7 +32,7 @@ public: explicit QRImageWidget(QWidget *parent = 0); QImage exportImage(); -public slots: +public Q_SLOTS: void saveImage(); void copyImage(); @@ -55,7 +55,7 @@ public: void setModel(OptionsModel *model); void setInfo(const SendCoinsRecipient &info); -private slots: +private Q_SLOTS: void on_btnCopyURI_clicked(); void on_btnCopyAddress_clicked(); diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 543b977d8f..5692a7aaef 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -119,7 +119,7 @@ QVariant RecentRequestsTableModel::headerData(int section, Qt::Orientation orien void RecentRequestsTableModel::updateAmountColumnTitle() { columns[Amount] = getAmountTitle(); - emit headerDataChanged(Qt::Horizontal,Amount,Amount); + Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount); } /** Gets title for amount column including current display unit if optionsModel reference available. */ @@ -214,7 +214,7 @@ void RecentRequestsTableModel::addNewRequest(RecentRequestEntry &recipient) void RecentRequestsTableModel::sort(int column, Qt::SortOrder order) { qSort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order)); - emit dataChanged(index(0, 0, QModelIndex()), index(list.size() - 1, NUMBER_OF_COLUMNS - 1, QModelIndex())); + Q_EMIT dataChanged(index(0, 0, QModelIndex()), index(list.size() - 1, NUMBER_OF_COLUMNS - 1, QModelIndex())); } void RecentRequestsTableModel::updateDisplayUnit() diff --git a/src/qt/recentrequeststablemodel.h b/src/qt/recentrequeststablemodel.h index 85bad126db..64faa72d45 100644 --- a/src/qt/recentrequeststablemodel.h +++ b/src/qt/recentrequeststablemodel.h @@ -89,7 +89,7 @@ public: void addNewRequest(const std::string &recipient); void addNewRequest(RecentRequestEntry &recipient); -public slots: +public Q_SLOTS: void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); void updateDisplayUnit(); diff --git a/src/qt/res/bitcoin-qt-res.rc b/src/qt/res/bitcoin-qt-res.rc index c0f3e2fb39..9f66d0af79 100644 --- a/src/qt/res/bitcoin-qt-res.rc +++ b/src/qt/res/bitcoin-qt-res.rc @@ -19,7 +19,7 @@ BEGIN BLOCK "040904E4" // U.S. English - multilingual (hex) BEGIN VALUE "CompanyName", "Bitcoin" - VALUE "FileDescription", "Bitcoin Core (OSS GUI client for Bitcoin)" + VALUE "FileDescription", "Bitcoin Core (GUI node for Bitcoin)" VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoin-qt" VALUE "LegalCopyright", COPYRIGHT_STR diff --git a/src/qt/res/icons/about_qt.png b/src/qt/res/icons/about_qt.png Binary files differindex dd27a99d0a..c40abfd3a6 100644 --- a/src/qt/res/icons/about_qt.png +++ b/src/qt/res/icons/about_qt.png diff --git a/src/qt/res/icons/clock1.png b/src/qt/res/icons/clock1.png Binary files differindex ceae5ed0d9..162204d1bb 100644 --- a/src/qt/res/icons/clock1.png +++ b/src/qt/res/icons/clock1.png diff --git a/src/qt/res/icons/clock2.png b/src/qt/res/icons/clock2.png Binary files differindex 159f69a8fc..8f4263a31c 100644 --- a/src/qt/res/icons/clock2.png +++ b/src/qt/res/icons/clock2.png diff --git a/src/qt/res/icons/clock3.png b/src/qt/res/icons/clock3.png Binary files differindex d668e35ffc..7f11a7566c 100644 --- a/src/qt/res/icons/clock3.png +++ b/src/qt/res/icons/clock3.png diff --git a/src/qt/res/icons/clock4.png b/src/qt/res/icons/clock4.png Binary files differindex 5ebf8ed7ac..fdd1a0fce3 100644 --- a/src/qt/res/icons/clock4.png +++ b/src/qt/res/icons/clock4.png diff --git a/src/qt/res/icons/clock5.png b/src/qt/res/icons/clock5.png Binary files differindex 96f15ef7d9..7d6556c6cf 100644 --- a/src/qt/res/icons/clock5.png +++ b/src/qt/res/icons/clock5.png diff --git a/src/qt/res/icons/connect0.png b/src/qt/res/icons/connect0.png Binary files differindex 58e2c3e965..ef708d81fb 100644 --- a/src/qt/res/icons/connect0.png +++ b/src/qt/res/icons/connect0.png diff --git a/src/qt/res/icons/connect1.png b/src/qt/res/icons/connect1.png Binary files differindex 949e7a922d..ed358e6f8e 100644 --- a/src/qt/res/icons/connect1.png +++ b/src/qt/res/icons/connect1.png diff --git a/src/qt/res/icons/connect2.png b/src/qt/res/icons/connect2.png Binary files differindex 143b2054fb..3bbb0d395c 100644 --- a/src/qt/res/icons/connect2.png +++ b/src/qt/res/icons/connect2.png diff --git a/src/qt/res/icons/connect3.png b/src/qt/res/icons/connect3.png Binary files differindex 143b2054fb..0db99ad8d3 100644 --- a/src/qt/res/icons/connect3.png +++ b/src/qt/res/icons/connect3.png diff --git a/src/qt/res/icons/connect4.png b/src/qt/res/icons/connect4.png Binary files differindex f96e3455ce..9dd19fc2bd 100644 --- a/src/qt/res/icons/connect4.png +++ b/src/qt/res/icons/connect4.png diff --git a/src/qt/res/icons/transaction0.png b/src/qt/res/icons/transaction0.png Binary files differindex 1091b86e68..72c44565ec 100644 --- a/src/qt/res/icons/transaction0.png +++ b/src/qt/res/icons/transaction0.png diff --git a/src/qt/res/icons/warning.png b/src/qt/res/icons/warning.png Binary files differnew file mode 100644 index 0000000000..6bc5ac7895 --- /dev/null +++ b/src/qt/res/icons/warning.png diff --git a/src/qt/res/movies/makespinner.sh b/src/qt/res/movies/makespinner.sh index 625fb17173..a4c2fddbbf 100755 --- a/src/qt/res/movies/makespinner.sh +++ b/src/qt/res/movies/makespinner.sh @@ -1,6 +1,7 @@ -for i in {1..35} +FRAMEDIR=$(dirname $0) +for i in {0..35} do - value=$(printf "%03d" $i) + frame=$(printf "%03d" $i) angle=$(($i * 10)) - convert spinner-000.png -background "rgba(0,0,0,0.0)" -distort SRT $angle spinner-$value.png + convert $FRAMEDIR/../src/spinner.png -background "rgba(0,0,0,0.0)" -distort SRT $angle $FRAMEDIR/spinner-$frame.png done diff --git a/src/qt/res/movies/spinner-000.png b/src/qt/res/movies/spinner-000.png Binary files differindex 1e92d859da..0dc48d0d8c 100644 --- a/src/qt/res/movies/spinner-000.png +++ b/src/qt/res/movies/spinner-000.png diff --git a/src/qt/res/src/clock_1.svg b/src/qt/res/src/clock_1.svg index 4e49772d26..2a3d84c2d0 100644 --- a/src/qt/res/src/clock_1.svg +++ b/src/qt/res/src/clock_1.svg @@ -9,5 +9,7 @@ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
</g>
-<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
+<path
+ d="M 478.3,253.4 297.6,184.6 c 0,0 0,78.8 0,118.2 0,117.5 -0.4,118.1 118.2,118.1 39.4,0 118.2,0 118.2,0 z"
+ id="polygon7" />
</svg>
diff --git a/src/qt/res/src/clock_2.svg b/src/qt/res/src/clock_2.svg index 995446e46e..2de8d467b7 100644 --- a/src/qt/res/src/clock_2.svg +++ b/src/qt/res/src/clock_2.svg @@ -9,6 +9,5 @@ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
</g>
-<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>
-<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
+<polygon points="465.2,601.6 534,420.9 478.3,253.4 297.6,184.6 297.6,420.9 297.6,657.3 "/>
</svg>
diff --git a/src/qt/res/src/clock_3.svg b/src/qt/res/src/clock_3.svg index ea47a84730..b691043e3e 100644 --- a/src/qt/res/src/clock_3.svg +++ b/src/qt/res/src/clock_3.svg @@ -9,7 +9,7 @@ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
</g>
-<polygon points="117,588.5 297.6,657.3 297.6,420.9 61.3,420.9 "/>
-<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>
-<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
+<path
+ d="M 465.2,601.6 534,420.9 478.3,253.4 297.6,184.6 c 0,0 0,78.8 0,118.2 0,117.7 0.4,118.1 -118.1,118.1 -39.4,0 -118.2,0 -118.2,0 l 55.7,167.6 180.6,68.8 z"
+ id="polygon7" />
</svg>
diff --git a/src/qt/res/src/clock_4.svg b/src/qt/res/src/clock_4.svg index 43160288d8..ea311f31e8 100644 --- a/src/qt/res/src/clock_4.svg +++ b/src/qt/res/src/clock_4.svg @@ -1,18 +1,23 @@ -<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 841.9 841.9" enable-background="new 0 0 841.9 841.9" xml:space="preserve">
-<g>
- <path d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1
- s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6
- c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
- c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
-</g>
-<polygon points="130.1,240.3 61.3,420.9 297.6,420.9 297.6,184.6 "/>
-<polygon points="117,588.5 297.6,657.3 297.6,420.9 61.3,420.9 "/>
-<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>
-<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
-<path fill="#FFFFFF" d="M293.5,452.6h99.6c14.9,0,24.8-9.9,24.8-24.8S408,403,393.1,403h-74.8V278.2c0-14.9-9.9-24.8-24.8-24.8
- c-14.9,0-24.8,9.9-24.8,24.8v149.6C268.7,440.2,278.7,452.6,293.5,452.6z"/>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xml:space="preserve" + enable-background="new 0 0 841.9 841.9" + viewBox="0 0 841.9 841.9" + y="0px" + x="0px" + id="Ebene_1" + version="1.1"><metadata + id="metadata15"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs + id="defs13" /><g + id="g3"><path + id="path5" + d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1 s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6 c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4 c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z" /></g><path + id="polygon7" + d="M 297.6 184.6 L 130.1 240.3 L 61.3 420.9 L 117 588.5 L 297.6 657.3 L 465.2 601.6 L 534 420.9 L 478.3 253.4 L 297.6 184.6 z M 293.5 253.4 C 308.4 253.4 318.3 263.3 318.3 278.2 L 318.3 403 L 393.1 403 C 408 403 417.9 412.9 417.9 427.8 C 417.9 442.7 408 452.6 393.1 452.6 L 293.5 452.6 C 278.7 452.6 268.7 440.2 268.7 427.8 L 268.7 278.2 C 268.7 263.3 278.6 253.4 293.5 253.4 z " /></svg>
\ No newline at end of file diff --git a/src/qt/res/src/connect-0.svg b/src/qt/res/src/connect-0.svg index bedbec7777..7d2afac622 100644 --- a/src/qt/res/src/connect-0.svg +++ b/src/qt/res/src/connect-0.svg @@ -1,11 +1,66 @@ -<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
-<path fill="none" stroke="#000000" stroke-miterlimit="10" d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0
- c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z M7.8,15.8c-0.5,0-1-0.2-1.4-0.6c-0.8-0.8-0.8-2,0-2.8
- c3.1-3.1,8.2-3.1,11.3,0c0.8,0.8,0.8,2,0,2.8c-0.8,0.8-2,0.8-2.8,0c-1.6-1.6-4.1-1.6-5.7,0C8.8,15.6,8.3,15.8,7.8,15.8z"/>
-<path fill="none" stroke="#000000" stroke-miterlimit="10" d="M20.5,11.5c-0.5,0-1-0.2-1.4-0.6C15.2,7,8.8,7,4.9,10.9
- c-0.8,0.8-2,0.8-2.8,0c-0.8-0.8-0.8-2,0-2.8c5.5-5.5,14.3-5.5,19.8,0c0.8,0.8,0.8,2,0,2.8C21.5,11.3,21,11.5,20.5,11.5z"/>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + id="svg2" + viewBox="0 0 24 24" + height="24" + width="24" + version="1.2"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <g + id="g4142" + transform="matrix(0,-1,-1,0,23.96,24)"> + <g + id="g4210" + transform="matrix(-1,0,0,1,59.86,-106.6)"> + <g + id="g4289" + transform="matrix(-1,0,0,1,-16.98,0.8136)"> + <g + id="g4291"> + <path + id="path4293" + d="m -65.35,116.3 0,3 0.5,0 c 0.54,0 1,0.5 1,1 l 0,2.6 c -1.15,0.5 -2,1.6 -2,3 0,2 1.59,3.5 3.5,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-2.3 -1.81,-4 -4,-4 z m 1,1.2 c 1.39,0.3 2.5,1.3 2.5,2.8 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.5,-1.1 -2.5,-2.5 0,-1.1 0.69,-2 1.66,-2.3 l 0.34,-0.1 0,-3.2 c 0,-0.9 -0.67,-1.5 -1.5,-1.8 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + <g + style="fill:#969696;fill-opacity:1" + id="g4295"> + <path + id="path4297" + d="m -67.35,106.1 c -1.94,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,2.2 1.79,4 4,4 l 0.5,0 0,-0.5 0,-2.5 -0.5,0 c -0.55,0 -1,-0.5 -1,-1 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.57,-3.5 -3.5,-3.5 z m 0,1 c 1.37,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,0.9 0.67,1.5 1.5,1.8 l 0,1 c -1.38,-0.3 -2.5,-1.4 -2.5,-2.8 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.12,-2.5 2.5,-2.5 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + <path + id="path4299" + d="m -57.35,106.1 c -1.93,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,0.5 -0.45,1 -1,1 l -4.85,0 3.17,3 1.68,0 c 2.21,0 4,-1.8 4,-4 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.56,-3.5 -3.5,-3.5 z m 0,1 c 1.38,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,1.6 -1.35,3 -3,3 l -1.81,0 -2.04,-1 3.85,0 c 1.11,0 2,-0.9 2,-2 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.13,-2.5 2.5,-2.5 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + </g> + <path + id="path4301" + d="m -69.84,116.3 c -2.19,0 -4,1.7 -4,4 l 0,2.6 c -1.14,0.6 -1.99,1.6 -1.99,3 0,2 1.6,3.5 3.51,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-0.5 0.45,-1 1,-1 l 5.01,0 -3.36,-3 z m 0,1 1.84,0 2.19,1 -4.01,0 c -1.11,0 -2,0.9 -2,2 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.51,-1.1 -2.51,-2.5 0,-1.1 0.7,-2 1.66,-2.3 l 0.33,-0.1 0,-0.4 0,-2.8 c 0,-1.7 1.33,-3 3,-3 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + </g> + </g> + </g> + <path + id="path4165" + d="m 12,8.77 c -0.84,0 -1.66,0.341 -2.254,0.937 -0.599,0.593 -0.942,1.403 -0.945,2.253 0,0.85 0.337,1.67 0.933,2.26 a 0.6001,0.6001 0 0 0 0,0 c 0.594,0.6 1.424,0.94 2.264,0.94 0.84,0 1.67,-0.34 2.26,-0.94 0.6,-0.59 0.94,-1.41 0.94,-2.26 0,-0.84 -0.34,-1.66 -0.95,-2.253 C 13.66,9.111 12.84,8.77 12,8.77 Z" + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> +</svg> diff --git a/src/qt/res/src/connect-1.svg b/src/qt/res/src/connect-1.svg index d3d4e46a41..d17928c97d 100644 --- a/src/qt/res/src/connect-1.svg +++ b/src/qt/res/src/connect-1.svg @@ -1,21 +1,69 @@ -<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
-<g>
- <path d="M12,11c1.9,0,3.6,0.7,4.9,2c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C14.6,13.5,13.3,13,12,13
- c-1.3,0-2.6,0.5-3.5,1.5c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C8.4,11.7,10.1,11,12,11 M12,17
- c0.3,0,0.5,0.1,0.7,0.3c0.2,0.2,0.3,0.4,0.3,0.7s-0.1,0.5-0.3,0.7C12.5,18.9,12.3,19,12,19c-0.3,0-0.5-0.1-0.7-0.3
- C11.1,18.5,11,18.3,11,18c0-0.3,0.1-0.5,0.3-0.7C11.5,17.1,11.7,17,12,17 M12,10c-2,0-4.1,0.8-5.7,2.3c-0.8,0.8-0.8,2,0,2.8
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C10,14.4,11,14,12,14c1,0,2,0.4,2.8,1.2c0.4,0.4,0.9,0.6,1.4,0.6s1-0.2,1.4-0.6
- c0.8-0.8,0.8-2,0-2.8C16.1,10.8,14,10,12,10L12,10z M12,16c-0.5,0-1,0.2-1.4,0.6c-0.8,0.8-0.8,2.1,0,2.8C11,19.8,11.5,20,12,20
- c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C13,16.2,12.5,16,12,16L12,16z"/>
-</g>
-<g>
- <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7
- c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4
- C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>
-</g>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.2" + width="24" + height="24" + viewBox="0 0 24 24" + id="svg2"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <g + id="g4210" + transform="translate(0,0.25)"> + <g + id="g4142" + transform="matrix(0,-1,-1,0,23.96,23.75)"> + <g + id="g4213" + transform="matrix(-1,0,0,1,59.86,-106.6)"> + <g + id="g4289" + transform="matrix(-1,0,0,1,-16.98,0.8136)"> + <g + id="g4291"> + <path + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + d="m -65.35,116.3 0,3 0.5,0 c 0.54,0 1,0.5 1,1 l 0,2.6 c -1.15,0.5 -2,1.6 -2,3 0,2 1.59,3.5 3.5,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-2.3 -1.81,-4 -4,-4 z m 1,1.2 c 1.39,0.3 2.5,1.3 2.5,2.8 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.5,-1.1 -2.5,-2.5 0,-1.1 0.69,-2 1.66,-2.3 l 0.34,-0.1 0,-3.2 c 0,-0.9 -0.67,-1.5 -1.5,-1.8 z" + id="path4293" /> + <g + id="g4295"> + <path + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + d="m -67.35,106.1 c -1.94,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,2.2 1.79,4 4,4 l 0.5,0 0,-0.5 0,-2.5 -0.5,0 c -0.55,0 -1,-0.5 -1,-1 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.57,-3.5 -3.5,-3.5 z m 0,1 c 1.37,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,0.9 0.67,1.5 1.5,1.8 l 0,1 c -1.38,-0.3 -2.5,-1.4 -2.5,-2.8 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.12,-2.5 2.5,-2.5 z" + id="path4297" /> + <path + id="path4145" + d="m -57.35,106 c -1.99,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,0.5 -0.41,0.9 -0.9,0.9 l -4.35,0 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 l 4.35,0 c 2.26,0 4.1,-1.9 4.1,-4.1 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.6,-3.6 -3.6,-3.6 z" + style="" /> + </g> + <path + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + d="m -69.84,116.3 c -2.19,0 -4,1.7 -4,4 l 0,2.6 c -1.14,0.6 -1.99,1.6 -1.99,3 0,2 1.6,3.5 3.51,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-0.5 0.45,-1 1,-1 l 5.01,0 -3.34,-3 z m 0,1 2.02,0 2.01,1 -4.01,0 c -1.11,0 -2,0.9 -2,2 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.51,-1.1 -2.51,-2.5 0,-1.1 0.7,-2 1.66,-2.3 l 0.33,-0.1 0,-0.4 0,-2.8 c 0,-1.7 1.33,-3 3,-3 z" + id="path4301" /> + </g> + </g> + </g> + <path + id="path4173" + d="m 12,8.764 c -0.84,0 -1.67,0.336 -2.264,0.931 a 0.6001,0.6001 0 0 0 -0,0 C 9.138,10.29 8.802,11.11 8.801,11.96 c 0,0.85 0.337,1.67 0.933,2.26 a 0.6001,0.6001 0 0 0 0,0 c 0.594,0.6 1.424,0.94 2.264,0.94 0.84,0 1.67,-0.34 2.26,-0.94 0.6,-0.59 0.94,-1.41 0.94,-2.26 0,-0.84 -0.34,-1.67 -0.94,-2.265 C 13.67,9.1 12.84,8.764 12,8.764 Z" + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> + </g> +</svg> diff --git a/src/qt/res/src/connect-2.svg b/src/qt/res/src/connect-2.svg index d5becc52b7..841ca6071d 100644 --- a/src/qt/res/src/connect-2.svg +++ b/src/qt/res/src/connect-2.svg @@ -1,22 +1,59 @@ -<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
-<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z"/>
-<g>
- <path d="M12,11c1.9,0,3.6,0.7,4.9,2c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C14.6,13.5,13.3,13,12,13
- c-1.3,0-2.6,0.5-3.5,1.5c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C8.4,11.7,10.1,11,12,11 M12,17
- c0.3,0,0.5,0.1,0.7,0.3c0.2,0.2,0.3,0.4,0.3,0.7s-0.1,0.5-0.3,0.7C12.5,18.9,12.3,19,12,19c-0.3,0-0.5-0.1-0.7-0.3
- C11.1,18.5,11,18.3,11,18c0-0.3,0.1-0.5,0.3-0.7C11.5,17.1,11.7,17,12,17 M12,10c-2,0-4.1,0.8-5.7,2.3c-0.8,0.8-0.8,2,0,2.8
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C10,14.4,11,14,12,14c1,0,2,0.4,2.8,1.2c0.4,0.4,0.9,0.6,1.4,0.6s1-0.2,1.4-0.6
- c0.8-0.8,0.8-2,0-2.8C16.1,10.8,14,10,12,10L12,10z M12,16c-0.5,0-1,0.2-1.4,0.6c-0.8,0.8-0.8,2.1,0,2.8C11,19.8,11.5,20,12,20
- c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C13,16.2,12.5,16,12,16L12,16z"/>
-</g>
-<g>
- <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7
- c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4
- C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>
-</g>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.2" + width="24" + height="24" + viewBox="0 0 24 24" + id="svg2"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <g + id="g4210" + transform="matrix(0,1,-1,0,130.6,-35.86)"> + <g + id="g4289" + transform="matrix(-1,0,0,1,-16.98,0.8136)"> + <g + id="g4291"> + <path + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + d="m -65.35,116.3 0,3 0.5,0 c 0.54,0 1,0.5 1,1 l 0,2.6 c -1.15,0.5 -2,1.6 -2,3 0,2 1.59,3.5 3.5,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-2.3 -1.81,-4 -4,-4 z m 1,1.2 c 1.39,0.3 2.5,1.3 2.5,2.8 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.5,-1.1 -2.5,-2.5 0,-1.1 0.69,-2 1.66,-2.3 l 0.34,-0.1 0,-3.2 c 0,-0.9 -0.67,-1.5 -1.5,-1.8 z" + id="path4293" /> + <g + id="g4295"> + <path + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + d="m -67.35,106.1 c -1.94,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,2.2 1.79,4 4,4 l 0.5,0 0,-0.5 0,-2.5 -0.5,0 c -0.55,0 -1,-0.5 -1,-1 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.57,-3.5 -3.5,-3.5 z m 0,1 c 1.37,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,0.9 0.67,1.5 1.5,1.8 l 0,1 c -1.38,-0.3 -2.5,-1.4 -2.5,-2.8 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.12,-2.5 2.5,-2.5 z" + id="path4297" /> + <path + id="path4142" + d="m -57.35,106 c -1.99,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,0.5 -0.41,0.9 -0.9,0.9 l -4.35,0 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 l 4.35,0 c 2.26,0 4.1,-1.9 4.1,-4.1 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.6,-3.6 -3.6,-3.6 z" /> + </g> + <path + id="path4148" + d="m -69.84,116.2 c -2.24,0 -4.1,1.8 -4.1,4.1 l 0,2.5 c -1.17,0.5 -1.99,1.7 -1.99,3.1 0,2 1.64,3.6 3.61,3.6 1.96,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-0.5 0.41,-0.9 0.9,-0.9 l 4.51,0 a 0.6001,0.6001 0 0 0 0.6,-0.6 l 0,-2 a 0.6001,0.6001 0 0 0 -0.6,-0.6 l -4.53,0 z" /> + </g> + </g> + <path + id="path4170" + d="m 47.86,115.4 c -0.84,0 -1.65,0.4 -2.24,1 -0.64,0.5 -0.96,1.3 -0.96,2.2 0,0.9 0.32,1.7 0.96,2.2 0.59,0.6 1.4,1 2.24,1 0.84,0 1.65,-0.4 2.24,-1 0.64,-0.5 0.96,-1.3 0.96,-2.2 0,-0.9 -0.32,-1.7 -0.96,-2.2 -0.59,-0.6 -1.4,-1 -2.24,-1 z" + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> +</svg> diff --git a/src/qt/res/src/connect-3.svg b/src/qt/res/src/connect-3.svg index 9bfa04721f..b06e67daf8 100644 --- a/src/qt/res/src/connect-3.svg +++ b/src/qt/res/src/connect-3.svg @@ -1,16 +1,72 @@ -<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
-<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z"/>
-<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z M7.8,15.8
- c-0.5,0-1-0.2-1.4-0.6c-0.8-0.8-0.8-2,0-2.8c3.1-3.1,8.2-3.1,11.3,0c0.8,0.8,0.8,2,0,2.8c-0.8,0.8-2,0.8-2.8,0
- c-1.6-1.6-4.1-1.6-5.7,0C8.8,15.6,8.3,15.8,7.8,15.8z"/>
-<g>
- <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7
- c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4
- C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>
-</g>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + id="svg2" + viewBox="0 0 24 24" + height="24" + width="24" + version="1.2"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <g + transform="translate(0.2636,0.29)" + id="g4160"> + <g + id="g4210" + transform="matrix(0,1,-1,0,130.3,-36.15)"> + <g + id="g4289" + transform="matrix(-1,0,0,1,-16.98,0.8136)"> + <g + id="g4291"> + <path + id="path4147" + d="m -64.85,116.2 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 c 0.48,0 0.9,0.4 0.9,0.9 l 0,2.4 c -1.18,0.6 -2,1.8 -2,3.2 0,2 1.64,3.6 3.6,3.6 1.97,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-2.3 -1.86,-4.1 -4.1,-4.1 z" + style="" /> + <g + id="g4295"> + <path + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + d="m -67.35,106.1 c -1.94,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,2.2 1.79,4 4,4 l 0.5,0 0,-0.5 0,-2.5 -0.5,0 c -0.55,0 -1,-0.5 -1,-1 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.57,-3.5 -3.5,-3.5 z m 0,1 c 1.37,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,0.9 0.67,1.5 1.5,1.8 l 0,1 c -1.38,-0.3 -2.5,-1.4 -2.5,-2.8 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.12,-2.5 2.5,-2.5 z" + id="path4297" /> + <path + id="path4145" + d="m -57.35,106 c -1.99,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,0.5 -0.41,0.9 -0.9,0.9 l -4.35,0 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 l 4.35,0 c 2.26,0 4.1,-1.9 4.1,-4.1 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.6,-3.6 -3.6,-3.6 z" + style="" /> + </g> + <path + id="path4149" + d="m -69.84,116.2 c -2.24,0 -4.1,1.8 -4.1,4.1 l 0,2.5 c -1.17,0.5 -1.99,1.7 -1.99,3.1 0,2 1.64,3.6 3.61,3.6 1.96,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-0.5 0.41,-0.9 0.9,-0.9 l 4.51,0 a 0.6001,0.6001 0 0 0 0.6,-0.6 l 0,-2 a 0.6001,0.6001 0 0 0 -0.6,-0.6 l -4.53,0 z" + style="" /> + </g> + </g> + </g> + <g + transform="matrix(0,1,1,0,-106.3,-36.15)" + id="g4142"> + <g + transform="matrix(-1,0,0,1,-16.98,0.8136)" + id="g4144" /> + </g> + </g> + <path + id="path4170" + d="m 15.2,12 c 0,-0.84 -0.4,-1.65 -1,-2.242 -0.5,-0.64 -1.3,-0.96 -2.2,-0.96 -0.9,0 -1.7,0.32 -2.2,0.96 -0.6,0.592 -1,1.402 -1,2.242 0,0.84 0.4,1.65 1,2.24 0.5,0.64 1.3,0.96 2.2,0.96 0.9,0 1.7,-0.32 2.2,-0.96 0.6,-0.59 1,-1.4 1,-2.24 z" + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> +</svg> diff --git a/src/qt/res/src/connect-4.svg b/src/qt/res/src/connect-4.svg new file mode 100644 index 0000000000..0abc7955fd --- /dev/null +++ b/src/qt/res/src/connect-4.svg @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.2" + width="24" + height="24" + viewBox="0 0 24 24" + id="svg2"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <g + id="g4142" + transform="matrix(0,-1,-1,0,23.96,24)"> + <g + transform="matrix(-1,0,0,1,59.86,-106.6)" + id="g4210"> + <g + transform="matrix(-1,0,0,1,-16.98,0.8136)" + id="g4289"> + <g + id="g4291"> + <path + id="path4153" + d="m -64.85,116.2 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 c 0.48,0 0.9,0.4 0.9,0.9 l 0,2.4 c -1.18,0.6 -2,1.8 -2,3.2 0,2 1.64,3.6 3.6,3.6 1.97,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-2.3 -1.86,-4.1 -4.1,-4.1 z" + style="" /> + <g + id="g4295"> + <path + id="path4149" + d="m -67.35,106 c -2,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,2.2 1.84,4.1 4.1,4.1 a 0.6001,0.6001 0 0 0 0.6,-0.6 l 0,-2 a 0.6001,0.6001 0 0 0 -0.6,-0.6 c -0.49,0 -0.9,-0.4 -0.9,-0.9 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.61,-3.6 -3.6,-3.6 z" + style="" /> + <path + id="path4147" + d="m -57.35,106 c -1.99,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,0.5 -0.41,0.9 -0.9,0.9 l -4.35,0 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 l 4.35,0 c 2.26,0 4.1,-1.9 4.1,-4.1 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.6,-3.6 -3.6,-3.6 z" + style="" /> + </g> + <path + id="path4155" + d="m -69.84,116.2 c -2.24,0 -4.1,1.8 -4.1,4.1 l 0,2.5 c -1.17,0.5 -1.99,1.7 -1.99,3.1 0,2 1.64,3.6 3.61,3.6 1.96,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-0.5 0.41,-0.9 0.9,-0.9 l 4.51,0 a 0.6001,0.6001 0 0 0 0.6,-0.6 l 0,-2 a 0.6001,0.6001 0 0 0 -0.6,-0.6 l -4.53,0 z" + style="" /> + </g> + </g> + </g> + </g> + <path + id="path4170" + d="m 15.2,12 c 0,-0.84 -0.4,-1.65 -1,-2.24 C 13.7,9.12 12.9,8.8 12,8.8 c -0.9,0 -1.7,0.32 -2.2,0.96 -0.6,0.59 -1,1.4 -1,2.24 0,0.84 0.4,1.65 1,2.24 0.5,0.64 1.3,0.96 2.2,0.96 0.9,0 1.7,-0.32 2.2,-0.96 0.6,-0.59 1,-1.4 1,-2.24 z" + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> +</svg> diff --git a/src/qt/res/src/qt.svg b/src/qt/res/src/qt.svg index 9ef54f493c..373c91f0c6 100644 --- a/src/qt/res/src/qt.svg +++ b/src/qt/res/src/qt.svg @@ -1,25 +1,26 @@ -<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 841.9 595.3" enable-background="new 0 0 841.9 595.3" xml:space="preserve">
-<g>
- <path d="M182.8,310c0-74.4,0-148.8,0-220.7c0-19.8,5-39.7,19.8-54.6c12.4-12.4,27.3-17.4,44.6-19.8c37.2-5,74.4,2.5,109.1,7.4
- C428.4,34.7,497.8,44.6,569.8,57c27.3,5,57,9.9,84.3,12.4c7.4,0,5,5,5,9.9c0,91.8,0,181.1,0,272.8c0,32.2,0,64.5,0,99.2
- c0,14.9-5,29.8-12.4,44.6c-9.9,14.9-22.3,22.3-39.7,27.3c-69.4,12.4-138.9,22.3-208.3,34.7c-57,9.9-114.1,19.8-171.1,29.8
- c-2.5,0-5,0-7.4-2.5c-12.4-14.9-22.3-24.8-32.2-34.7c-2.5-2.5-2.5-7.4-2.5-9.9c0-71.9,0-143.9,0-215.8
- C182.8,320,182.8,315,182.8,310z M430.9,436.5c9.9-7.4,19.8-12.4,29.8-19.8c14.9-14.9,24.8-32.2,29.8-54.6
- c12.4-54.6,14.9-111.6,0-166.2c-12.4-47.1-42.2-74.4-84.3-79.4c-37.2-2.5-67,7.4-86.8,39.7c-7.4,14.9-12.4,29.8-14.9,44.6
- c-9.9,39.7-9.9,81.9-5,121.5c2.5,22.3,7.4,44.6,17.4,67c12.4,24.8,29.8,42.2,54.6,49.6c2.5,0,5,2.5,5,5c5,12.4,7.4,22.3,12.4,34.7
- s17.4,19.8,32.2,22.3c14.9,2.5,27.3,2.5,42.2,0c2.5,0,2.5-2.5,2.5-2.5c0-9.9,0-22.3,0-32.2C438.3,461.3,433.3,456.4,430.9,436.5z
- M505.3,191c0,12.4,0,22.3,0,34.7c0,2.5,2.5,2.5,5,2.5c5,0,7.4,0,12.4,0c0,2.5,0,5,0,9.9c0,44.6,0,86.8,0,131.5
- c0,7.4,0,17.4,2.5,24.8c2.5,12.4,12.4,22.3,24.8,24.8c19.8,5,37.2-2.5,54.6-9.9l2.5-2.5c0-9.9,0-19.8,0-29.8
- c-7.4,2.5-14.9,5-22.3,5s-12.4-2.5-14.9-9.9c0-5-2.5-9.9-2.5-14.9c0-39.7,0-79.4,0-119.1c0-2.5,0-5,0-7.4c9.9,0,19.8,0,29.8,2.5
- c5,0,7.4-2.5,7.4-7.4c0-7.4,0-14.9,0-22.3c0-5-2.5-7.4-7.4-7.4c-7.4,0-14.9-2.5-22.3-2.5c-5,0-7.4-2.5-7.4-7.4
- c0-14.9,0-29.8,0-42.2c0-5-2.5-5-5-7.4c-5,0-12.4,0-17.4-2.5s-7.4,0-9.9,7.4c-2.5,17.4-7.4,32.2-12.4,49.6
- C520.2,191,512.7,191,505.3,191z"/>
- <path d="M443.3,277.8c-2.5,27.3-5,57-9.9,84.3c0,7.4-5,17.4-9.9,24.8c-12.4,17.4-32.2,14.9-44.6-2.5c-9.9-14.9-12.4-32.2-14.9-49.6
- c-5-42.2-5-81.9,0-124c5-12.4,7.4-24.8,14.9-37.2c12.4-17.4,34.7-17.4,47.1-2.5c2.5,5,7.4,9.9,7.4,14.9c2.5,9.9,5,19.8,7.4,32.2
- c2.5,9.9,2.5,22.3,2.5,34.7C440.8,260.4,440.8,270.4,443.3,277.8L443.3,277.8z"/>
-</g>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.1" + id="Ebene_1" + x="0px" + y="0px" + viewBox="0 0 609.4 609.4" + enable-background="new 0 0 841.9 595.3" + xml:space="preserve" + width="609.4" + height="609.4"><metadata + id="metadata13"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs + id="defs11" /><g + id="g4151" + transform="matrix(2.553,0,0,2.553,-2149,281.5)"><path + id="path26" + transform="matrix(0.3917,0,0,0.3917,841.8,-110.3)" + d="M 153.7 16.9 C 115 16.44 69.7 31.67 67.96 86.81 L 67.96 550.7 L 105 592.4 L 495.9 526.7 C 521.4 522.1 541.9 490.2 541.9 455.9 L 541.9 77.77 L 183.4 18.97 C 179.4 18.3 161.4 17 157.5 16.99 C 156.2 16.94 155 16.91 153.7 16.9 z M 273.5 124.1 C 278.1 124.1 282.7 124.3 287.3 124.9 L 287.3 125 C 320 128.8 343.7 144.2 359.3 170.9 C 374.6 197.1 382 234.6 382 284 C 382 329.2 376.4 364.7 365.4 390.7 C 354.2 417.2 337.1 434.6 313.4 442.8 C 315.9 455 319.5 463.2 324.1 467.5 C 326.9 469.8 330.7 471.4 335.3 471.9 L 335.6 471.9 L 336.3 471.9 L 341.5 471.9 C 343.5 471.9 344.5 472.4 348.3 471.9 L 348.3 507.9 L 332 510.2 C 327.2 510.7 322.6 510.9 318.2 510.9 C 303.9 510.9 292.4 507.6 283.5 500.5 C 272 491.3 263.6 473.4 258.2 447.1 C 233.2 441.8 213.5 425.9 200 399.1 C 186.5 372.1 179.3 332.2 179.3 280.4 C 179.3 224.5 189 183.2 207.7 157 C 223.8 134.9 245.7 124.1 273.5 124.1 z M 424.4 143.5 L 455.1 146.9 L 455.1 202.2 L 488.2 204.8 L 488.2 239.5 L 455.1 237.8 L 455.1 364.7 C 455.1 375.6 457.6 382.8 460.2 386.1 C 460.2 388.9 465.3 390.4 467.8 390.4 L 470.4 390.4 C 478 389.9 485.7 387.9 493.4 384.1 L 493.4 415.7 C 478 422.1 465.3 425.7 450 426.9 C 450 427.2 447.4 427.2 444.8 427.2 C 432.1 427.2 424.4 423.6 416.8 416.5 C 409.1 408.1 404 394.5 404 376.1 L 404 235.6 L 390.2 234.8 L 390.2 197.6 L 411.7 199.1 L 424.4 143.5 z M 284.5 166.4 C 272.5 166.4 263.3 173.3 256.9 187.3 C 250.1 202.5 246.7 233.9 246.7 281.7 C 246.7 327.6 250.1 360.3 256.9 379.5 C 263.3 397.8 273 406.8 285.8 406.8 L 287.3 406.8 C 300.1 406 309.5 397.1 316.2 380.5 C 322.6 363.9 325.6 331.5 325.6 283 C 325.6 239.4 322.6 209.5 316.2 193 C 309.8 176.4 300.1 167.5 287.3 166.4 L 284.5 166.4 z " + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></svg>
\ No newline at end of file diff --git a/src/qt/res/spinner.png b/src/qt/res/src/spinner.png Binary files differindex b296a58481..b296a58481 100644 --- a/src/qt/res/spinner.png +++ b/src/qt/res/src/spinner.png diff --git a/src/qt/res/src/transaction0.svg b/src/qt/res/src/transaction0.svg new file mode 100644 index 0000000000..e7fcd8214c --- /dev/null +++ b/src/qt/res/src/transaction0.svg @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.1" + id="svg4142" + viewBox="0 0 128 127.9" + height="36.12mm" + width="36.12mm"> + <defs + id="defs4144" /> + <metadata + id="metadata4147"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + id="layer1" + transform="translate(-284.4,-501.6)"> + <path + id="path4792" + d="m 348.8,513.8 c -12.7,-0.7 -24.9,9.1 -27,21.7 -3.8,8.8 7.2,13.7 13.7,9.2 3.1,-7.5 9.4,-17.9 18.9,-11.6 9.7,6.1 2.1,17.6 -3,24.1 -6.1,7.8 -11.4,14.8 -8.9,23 5.4,17.7 10.8,3.7 12.8,-0.1 4.3,-8.2 6,-8.8 11.5,-16.1 6.4,-8.6 11.6,-19.9 7.7,-30.8 -2.8,-11.5 -13.9,-19.9 -25.7,-19.4 z m -0.7,84.7 c -11.4,2.4 -9.1,19.5 2.7,17.1 11.8,-2.4 8.7,-19.5 -2.7,-17.1 z" + style="fill:#000000" /> + </g> +</svg> diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 29c971ec79..72a3023c9a 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -3,31 +3,34 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "rpcconsole.h" -#include "ui_rpcconsole.h" +#include "ui_debugwindow.h" +#include "bantablemodel.h" #include "clientmodel.h" #include "guiutil.h" -#include "peertablemodel.h" -#include "scicon.h" +#include "platformstyle.h" +#include "bantablemodel.h" -#include "main.h" #include "chainparams.h" #include "rpcserver.h" #include "rpcclient.h" #include "util.h" -#include "json/json_spirit_value.h" - #include <openssl/crypto.h> +#include "univalue/univalue.h" + #ifdef ENABLE_WALLET #include <db_cxx.h> #endif #include <QKeyEvent> +#include <QMenu> #include <QScrollBar> +#include <QSignalMapper> #include <QThread> #include <QTime> +#include <QTimer> #if QT_VERSION < 0x050000 #include <QUrl> @@ -59,13 +62,47 @@ class RPCExecutor : public QObject { Q_OBJECT -public slots: +public Q_SLOTS: void request(const QString &command); -signals: +Q_SIGNALS: void reply(int category, const QString &command); }; +/** Class for handling RPC timers + * (used for e.g. re-locking the wallet after a timeout) + */ +class QtRPCTimerBase: public QObject, public RPCTimerBase +{ + Q_OBJECT +public: + QtRPCTimerBase(boost::function<void(void)>& func, int64_t millis): + func(func) + { + timer.setSingleShot(true); + connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); + timer.start(millis); + } + ~QtRPCTimerBase() {} +private Q_SLOTS: + void timeout() { func(); } +private: + QTimer timer; + boost::function<void(void)> func; +}; + +class QtRPCTimerInterface: public RPCTimerInterface +{ +public: + ~QtRPCTimerInterface() {} + const char *Name() { return "Qt"; } + RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis) + { + return new QtRPCTimerBase(func, millis); + } +}; + + #include "rpcconsole.moc" /** @@ -94,7 +131,7 @@ bool parseCommandLine(std::vector<std::string> &args, const std::string &strComm STATE_ESCAPE_DOUBLEQUOTED } state = STATE_EATING_SPACES; std::string curarg; - foreach(char ch, strCommand) + Q_FOREACH(char ch, strCommand) { switch(state) { @@ -157,7 +194,7 @@ void RPCExecutor::request(const QString &command) std::vector<std::string> args; if(!parseCommandLine(args, command.toStdString())) { - emit reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \"")); + Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \"")); return; } if(args.empty()) @@ -167,53 +204,56 @@ void RPCExecutor::request(const QString &command) std::string strPrint; // Convert argument list to JSON objects in method-dependent way, // and pass it along with the method name to the dispatcher. - json_spirit::Value result = tableRPC.execute( + UniValue result = tableRPC.execute( args[0], RPCConvertValues(args[0], std::vector<std::string>(args.begin() + 1, args.end()))); // Format result reply - if (result.type() == json_spirit::null_type) + if (result.isNull()) strPrint = ""; - else if (result.type() == json_spirit::str_type) + else if (result.isStr()) strPrint = result.get_str(); else - strPrint = write_string(result, true); + strPrint = result.write(2); - emit reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint)); + Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint)); } - catch (const json_spirit::Object& objError) + catch (UniValue& objError) { try // Nice formatting for standard-format error { int code = find_value(objError, "code").get_int(); std::string message = find_value(objError, "message").get_str(); - emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(message) + " (code " + QString::number(code) + ")"); + Q_EMIT reply(RPCConsole::CMD_ERROR, QString::fromStdString(message) + " (code " + QString::number(code) + ")"); } catch (const std::runtime_error&) // raised when converting to invalid type, i.e. missing code or message { // Show raw JSON object - emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false))); + Q_EMIT reply(RPCConsole::CMD_ERROR, QString::fromStdString(objError.write())); } } catch (const std::exception& e) { - emit reply(RPCConsole::CMD_ERROR, QString("Error: ") + QString::fromStdString(e.what())); + Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Error: ") + QString::fromStdString(e.what())); } } -RPCConsole::RPCConsole(QWidget *parent) : +RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : QWidget(parent), ui(new Ui::RPCConsole), clientModel(0), historyPtr(0), - cachedNodeid(-1) + cachedNodeid(-1), + platformStyle(platformStyle), + peersTableContextMenu(0), + banTableContextMenu(0) { ui->setupUi(this); GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this); -#ifndef Q_OS_MAC - ui->openDebugLogfileButton->setIcon(SingleColorIcon(":/icons/export")); -#endif - ui->clearButton->setIcon(SingleColorIcon(":/icons/remove")); + if (platformStyle->getImagesOnButtons()) { + ui->openDebugLogfileButton->setIcon(platformStyle->SingleColorIcon(":/icons/export")); + } + ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); // Install event filter for up and down arrow ui->lineEdit->installEventFilter(this); @@ -230,6 +270,9 @@ RPCConsole::RPCConsole(QWidget *parent) : ui->label_berkeleyDBVersion->hide(); ui->berkeleyDBVersion->hide(); #endif + // Register RPC timer interface + rpcTimerInterface = new QtRPCTimerInterface(); + RPCRegisterTimerInterface(rpcTimerInterface); startExecutor(); setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS); @@ -243,7 +286,9 @@ RPCConsole::RPCConsole(QWidget *parent) : RPCConsole::~RPCConsole() { GUIUtil::saveWindowGeometry("nRPCConsoleWindow", this); - emit stopExecutor(); + Q_EMIT stopExecutor(); + RPCUnregisterTimerInterface(rpcTimerInterface); + delete rpcTimerInterface; delete ui; } @@ -287,8 +332,7 @@ void RPCConsole::setClientModel(ClientModel *model) { clientModel = model; ui->trafficGraph->setClientModel(model); - if(model) - { + if (model && clientModel->getPeerTableModel() && clientModel->getBanTableModel()) { // Keep up to date with client setNumConnections(model->getNumConnections()); connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); @@ -305,21 +349,85 @@ void RPCConsole::setClientModel(ClientModel *model) ui->peerWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows); ui->peerWidget->setSelectionMode(QAbstractItemView::SingleSelection); + ui->peerWidget->setContextMenuPolicy(Qt::CustomContextMenu); ui->peerWidget->setColumnWidth(PeerTableModel::Address, ADDRESS_COLUMN_WIDTH); ui->peerWidget->setColumnWidth(PeerTableModel::Subversion, SUBVERSION_COLUMN_WIDTH); ui->peerWidget->setColumnWidth(PeerTableModel::Ping, PING_COLUMN_WIDTH); - - // connect the peerWidget selection model to our peerSelected() handler + ui->peerWidget->horizontalHeader()->setStretchLastSection(true); + + // create peer table context menu actions + QAction* disconnectAction = new QAction(tr("&Disconnect Node"), this); + QAction* banAction1h = new QAction(tr("Ban Node for") + " " + tr("1 &hour"), this); + QAction* banAction24h = new QAction(tr("Ban Node for") + " " + tr("1 &day"), this); + QAction* banAction7d = new QAction(tr("Ban Node for") + " " + tr("1 &week"), this); + QAction* banAction365d = new QAction(tr("Ban Node for") + " " + tr("1 &year"), this); + + // create peer table context menu + peersTableContextMenu = new QMenu(); + peersTableContextMenu->addAction(disconnectAction); + peersTableContextMenu->addAction(banAction1h); + peersTableContextMenu->addAction(banAction24h); + peersTableContextMenu->addAction(banAction7d); + peersTableContextMenu->addAction(banAction365d); + + // Add a signal mapping to allow dynamic context menu arguments. + // We need to use int (instead of int64_t), because signal mapper only supports + // int or objects, which is okay because max bantime (1 year) is < int_max. + QSignalMapper* signalMapper = new QSignalMapper(this); + signalMapper->setMapping(banAction1h, 60*60); + signalMapper->setMapping(banAction24h, 60*60*24); + signalMapper->setMapping(banAction7d, 60*60*24*7); + signalMapper->setMapping(banAction365d, 60*60*24*365); + connect(banAction1h, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(banAction24h, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(banAction7d, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(banAction365d, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(banSelectedNode(int))); + + // peer table context menu signals + connect(ui->peerWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showPeersTableContextMenu(const QPoint&))); + connect(disconnectAction, SIGNAL(triggered()), this, SLOT(disconnectSelectedNode())); + + // peer table signal handling - update peer details when selecting new node connect(ui->peerWidget->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), - this, SLOT(peerSelected(const QItemSelection &, const QItemSelection &))); + this, SLOT(peerSelected(const QItemSelection &, const QItemSelection &))); + // peer table signal handling - update peer details when new nodes are added to the model connect(model->getPeerTableModel(), SIGNAL(layoutChanged()), this, SLOT(peerLayoutChanged())); + // set up ban table + ui->banlistWidget->setModel(model->getBanTableModel()); + ui->banlistWidget->verticalHeader()->hide(); + ui->banlistWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->banlistWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->banlistWidget->setSelectionMode(QAbstractItemView::SingleSelection); + ui->banlistWidget->setContextMenuPolicy(Qt::CustomContextMenu); + ui->banlistWidget->setColumnWidth(BanTableModel::Address, BANSUBNET_COLUMN_WIDTH); + ui->banlistWidget->setColumnWidth(BanTableModel::Bantime, BANTIME_COLUMN_WIDTH); + ui->banlistWidget->horizontalHeader()->setStretchLastSection(true); + + // create ban table context menu action + QAction* unbanAction = new QAction(tr("&Unban Node"), this); + + // create ban table context menu + banTableContextMenu = new QMenu(); + banTableContextMenu->addAction(unbanAction); + + // ban table context menu signals + connect(ui->banlistWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showBanTableContextMenu(const QPoint&))); + connect(unbanAction, SIGNAL(triggered()), this, SLOT(unbanSelectedNode())); + + // ban table signal handling - clear peer details when clicking a peer in the ban table + connect(ui->banlistWidget, SIGNAL(clicked(const QModelIndex&)), this, SLOT(clearSelectedNode())); + // ban table signal handling - ensure ban table is shown or hidden (if empty) + connect(model->getBanTableModel(), SIGNAL(layoutChanged()), this, SLOT(showOrHideBanTableIfRequired())); + showOrHideBanTableIfRequired(); + // Provide initial values ui->clientVersion->setText(model->formatFullVersion()); + ui->clientUserAgent->setText(model->formatSubVersion()); ui->clientName->setText(model->clientName()); ui->buildDate->setText(model->formatBuildDate()); ui->startupTime->setText(model->formatClientStartupTime()); - ui->networkName->setText(QString::fromStdString(Params().NetworkIDString())); } } @@ -350,7 +458,7 @@ void RPCConsole::clear() ui->messagesWidget->document()->addResource( QTextDocument::ImageResource, QUrl(ICON_MAPPING[i].url), - SingleColorImage(ICON_MAPPING[i].source, SingleColor()).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + platformStyle->SingleColorImage(ICON_MAPPING[i].source).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } // Set default style sheet @@ -417,7 +525,7 @@ void RPCConsole::on_lineEdit_returnPressed() if(!cmd.isEmpty()) { message(CMD_REQUEST, cmd); - emit cmdRequest(cmd); + Q_EMIT cmdRequest(cmd); // Remove command, if already in history history.removeOne(cmd); // Append command to history @@ -471,10 +579,10 @@ void RPCConsole::startExecutor() void RPCConsole::on_tabWidget_currentChanged(int index) { - if(ui->tabWidget->widget(index) == ui->tab_console) - { + if (ui->tabWidget->widget(index) == ui->tab_console) ui->lineEdit->setFocus(); - } + else if (ui->tabWidget->widget(index) != ui->tab_peers) + clearSelectedNode(); } void RPCConsole::on_openDebugLogfileButton_clicked() @@ -523,7 +631,7 @@ void RPCConsole::peerSelected(const QItemSelection &selected, const QItemSelecti { Q_UNUSED(deselected); - if (!clientModel || selected.indexes().isEmpty()) + if (!clientModel || !clientModel->getPeerTableModel() || selected.indexes().isEmpty()) return; const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(selected.indexes().first().row()); @@ -533,7 +641,7 @@ void RPCConsole::peerSelected(const QItemSelection &selected, const QItemSelecti void RPCConsole::peerLayoutChanged() { - if (!clientModel) + if (!clientModel || !clientModel->getPeerTableModel()) return; const CNodeCombinedStats *stats = NULL; @@ -544,12 +652,11 @@ void RPCConsole::peerLayoutChanged() return; // find the currently selected row - int selectedRow; + int selectedRow = -1; QModelIndexList selectedModelIndex = ui->peerWidget->selectionModel()->selectedIndexes(); - if (selectedModelIndex.isEmpty()) - selectedRow = -1; - else + if (!selectedModelIndex.isEmpty()) { selectedRow = selectedModelIndex.first().row(); + } // check if our detail node has a row in the table (it may not necessarily // be at selectedRow since its position can change after a layout change) @@ -557,11 +664,8 @@ void RPCConsole::peerLayoutChanged() if (detailNodeRow < 0) { - // detail node dissapeared from table (node disconnected) + // detail node disappeared from table (node disconnected) fUnselect = true; - cachedNodeid = -1; - ui->detailWidget->hide(); - ui->peerHeading->setText(tr("Select a peer to view detailed information.")); } else { @@ -576,10 +680,8 @@ void RPCConsole::peerLayoutChanged() stats = clientModel->getPeerTableModel()->getNodeStats(detailNodeRow); } - if (fUnselect && selectedRow >= 0) - { - ui->peerWidget->selectionModel()->select(QItemSelection(selectedModelIndex.first(), selectedModelIndex.last()), - QItemSelectionModel::Deselect); + if (fUnselect && selectedRow >= 0) { + clearSelectedNode(); } if (fReselect) @@ -597,7 +699,8 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats) cachedNodeid = stats->nodeStats.nodeid; // update the detail ui with latest node information - QString peerAddrDetails(QString::fromStdString(stats->nodeStats.addrName)); + QString peerAddrDetails(QString::fromStdString(stats->nodeStats.addrName) + " "); + peerAddrDetails += tr("(node id: %1)").arg(QString::number(stats->nodeStats.nodeid)); if (!stats->nodeStats.addrLocal.empty()) peerAddrDetails += "<br />" + tr("via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal)); ui->peerHeading->setText(peerAddrDetails); @@ -608,11 +711,13 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats) ui->peerBytesRecv->setText(FormatBytes(stats->nodeStats.nRecvBytes)); ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nTimeConnected)); ui->peerPingTime->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingTime)); + ui->peerPingWait->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingWait)); ui->timeoffset->setText(GUIUtil::formatTimeOffset(stats->nodeStats.nTimeOffset)); - ui->peerVersion->setText(QString("%1").arg(stats->nodeStats.nVersion)); + ui->peerVersion->setText(QString("%1").arg(QString::number(stats->nodeStats.nVersion))); ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer)); ui->peerDirection->setText(stats->nodeStats.fInbound ? tr("Inbound") : tr("Outbound")); - ui->peerHeight->setText(QString("%1").arg(stats->nodeStats.nStartingHeight)); + ui->peerHeight->setText(QString("%1").arg(QString::number(stats->nodeStats.nStartingHeight))); + ui->peerWhitelisted->setText(stats->nodeStats.fWhitelisted ? tr("Yes") : tr("No")); // This check fails for example if the lock was busy and // nodeStateStats couldn't be fetched. @@ -625,9 +730,12 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats) ui->peerSyncHeight->setText(QString("%1").arg(stats->nodeStateStats.nSyncHeight)); else ui->peerSyncHeight->setText(tr("Unknown")); - } else { - ui->peerBanScore->setText(tr("Fetching...")); - ui->peerSyncHeight->setText(tr("Fetching...")); + + // Common height is init to -1 + if (stats->nodeStateStats.nCommonHeight > -1) + ui->peerCommonHeight->setText(QString("%1").arg(stats->nodeStateStats.nCommonHeight)); + else + ui->peerCommonHeight->setText(tr("Unknown")); } ui->detailWidget->show(); @@ -642,7 +750,7 @@ void RPCConsole::showEvent(QShowEvent *event) { QWidget::showEvent(event); - if (!clientModel) + if (!clientModel || !clientModel->getPeerTableModel()) return; // start PeerTableModel auto refresh @@ -653,9 +761,92 @@ void RPCConsole::hideEvent(QHideEvent *event) { QWidget::hideEvent(event); - if (!clientModel) + if (!clientModel || !clientModel->getPeerTableModel()) return; // stop PeerTableModel auto refresh clientModel->getPeerTableModel()->stopAutoRefresh(); } + +void RPCConsole::showPeersTableContextMenu(const QPoint& point) +{ + QModelIndex index = ui->peerWidget->indexAt(point); + if (index.isValid()) + peersTableContextMenu->exec(QCursor::pos()); +} + +void RPCConsole::showBanTableContextMenu(const QPoint& point) +{ + QModelIndex index = ui->banlistWidget->indexAt(point); + if (index.isValid()) + banTableContextMenu->exec(QCursor::pos()); +} + +void RPCConsole::disconnectSelectedNode() +{ + // Get currently selected peer address + QString strNode = GUIUtil::getEntryData(ui->peerWidget, 0, PeerTableModel::Address); + // Find the node, disconnect it and clear the selected node + if (CNode *bannedNode = FindNode(strNode.toStdString())) { + bannedNode->fDisconnect = true; + clearSelectedNode(); + } +} + +void RPCConsole::banSelectedNode(int bantime) +{ + if (!clientModel) + return; + + // 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())) { + 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(); + } +} + +void RPCConsole::unbanSelectedNode() +{ + if (!clientModel) + return; + + // Get currently selected ban address + QString strNode = GUIUtil::getEntryData(ui->banlistWidget, 0, BanTableModel::Address); + CSubNet possibleSubnet(strNode.toStdString()); + + if (possibleSubnet.IsValid()) + { + CNode::Unban(possibleSubnet); + DumpBanlist(); + clientModel->getBanTableModel()->refresh(); + } +} + +void RPCConsole::clearSelectedNode() +{ + ui->peerWidget->selectionModel()->clearSelection(); + cachedNodeid = -1; + ui->detailWidget->hide(); + ui->peerHeading->setText(tr("Select a peer to view detailed information.")); +} + +void RPCConsole::showOrHideBanTableIfRequired() +{ + if (!clientModel) + return; + + bool visible = clientModel->getBanTableModel()->shouldShow(); + ui->banlistWidget->setVisible(visible); + ui->banHeading->setVisible(visible); +}
\ No newline at end of file diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 8737be35d1..b86f776786 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -13,12 +13,15 @@ #include <QWidget> class ClientModel; +class PlatformStyle; +class RPCTimerInterface; namespace Ui { class RPCConsole; } QT_BEGIN_NAMESPACE +class QMenu; class QItemSelection; QT_END_NAMESPACE @@ -28,7 +31,7 @@ class RPCConsole: public QWidget Q_OBJECT public: - explicit RPCConsole(QWidget *parent); + explicit RPCConsole(const PlatformStyle *platformStyle, QWidget *parent); ~RPCConsole(); void setClientModel(ClientModel *model); @@ -45,7 +48,7 @@ protected: virtual bool eventFilter(QObject* obj, QEvent *event); void keyPressEvent(QKeyEvent *); -private slots: +private Q_SLOTS: void on_lineEdit_returnPressed(); void on_tabWidget_currentChanged(int index); /** open the debug.log from the current datadir */ @@ -57,8 +60,16 @@ private slots: void resizeEvent(QResizeEvent *event); void showEvent(QShowEvent *event); void hideEvent(QHideEvent *event); - -public slots: + /** Show custom context menu on Peers tab */ + void showPeersTableContextMenu(const QPoint& point); + /** Show custom context menu on Bans tab */ + void showBanTableContextMenu(const QPoint& point); + /** Hides ban table if no bans are present */ + void showOrHideBanTableIfRequired(); + /** clear the selected node */ + void clearSelectedNode(); + +public Q_SLOTS: void clear(); void message(int category, const QString &message, bool html = false); /** Set number of connections shown in the UI */ @@ -73,8 +84,14 @@ public slots: void peerSelected(const QItemSelection &selected, const QItemSelection &deselected); /** Handle updated peer information */ void peerLayoutChanged(); - -signals: + /** Disconnect a selected node on the Peers tab */ + void disconnectSelectedNode(); + /** Ban a selected node on the Peers tab */ + void banSelectedNode(int bantime); + /** Unban a selected node on the Bans tab */ + void unbanSelectedNode(); + +Q_SIGNALS: // For RPC command executor void stopExecutor(); void cmdRequest(const QString &command); @@ -90,7 +107,10 @@ private: { ADDRESS_COLUMN_WIDTH = 200, SUBVERSION_COLUMN_WIDTH = 100, - PING_COLUMN_WIDTH = 80 + PING_COLUMN_WIDTH = 80, + BANSUBNET_COLUMN_WIDTH = 200, + BANTIME_COLUMN_WIDTH = 250 + }; Ui::RPCConsole *ui; @@ -98,6 +118,10 @@ private: QStringList history; int historyPtr; NodeId cachedNodeid; + const PlatformStyle *platformStyle; + RPCTimerInterface *rpcTimerInterface; + QMenu *peersTableContextMenu; + QMenu *banTableContextMenu; }; #endif // BITCOIN_QT_RPCCONSOLE_H diff --git a/src/qt/scicon.cpp b/src/qt/scicon.cpp deleted file mode 100644 index a0ffcd82a9..0000000000 --- a/src/qt/scicon.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "scicon.h" - -#include <QApplication> -#include <QColor> -#include <QIcon> -#include <QImage> -#include <QPalette> -#include <QPixmap> - -static void MakeSingleColorImage(QImage& img, const QColor& colorbase) -{ - img = img.convertToFormat(QImage::Format_ARGB32); - for (int x = img.width(); x--; ) - { - for (int y = img.height(); y--; ) - { - const QRgb rgb = img.pixel(x, y); - img.setPixel(x, y, qRgba(colorbase.red(), colorbase.green(), colorbase.blue(), qAlpha(rgb))); - } - } -} - -QImage SingleColorImage(const QString& filename, const QColor& colorbase) -{ - QImage img(filename); - MakeSingleColorImage(img, colorbase); - return img; -} - -QIcon SingleColorIcon(const QIcon& ico, const QColor& colorbase) -{ - QIcon new_ico; - QSize sz; - Q_FOREACH(sz, ico.availableSizes()) - { - QImage img(ico.pixmap(sz).toImage()); - MakeSingleColorImage(img, colorbase); - new_ico.addPixmap(QPixmap::fromImage(img)); - } - return new_ico; -} - -QIcon SingleColorIcon(const QString& filename, const QColor& colorbase) -{ - return QIcon(QPixmap::fromImage(SingleColorImage(filename, colorbase))); -} - -QColor SingleColor() -{ - const QColor colorHighlightBg(QApplication::palette().color(QPalette::Highlight)); - const QColor colorHighlightFg(QApplication::palette().color(QPalette::HighlightedText)); - const QColor colorText(QApplication::palette().color(QPalette::WindowText)); - const int colorTextLightness = colorText.lightness(); - QColor colorbase; - if (abs(colorHighlightBg.lightness() - colorTextLightness) < abs(colorHighlightFg.lightness() - colorTextLightness)) - colorbase = colorHighlightBg; - else - colorbase = colorHighlightFg; - return colorbase; -} - -QIcon SingleColorIcon(const QString& filename) -{ - return SingleColorIcon(filename, SingleColor()); -} - -static QColor TextColor() -{ - return QColor(QApplication::palette().color(QPalette::WindowText)); -} - -QIcon TextColorIcon(const QString& filename) -{ - return SingleColorIcon(filename, TextColor()); -} - -QIcon TextColorIcon(const QIcon& ico) -{ - return SingleColorIcon(ico, TextColor()); -} diff --git a/src/qt/scicon.h b/src/qt/scicon.h deleted file mode 100644 index 1388069ddb..0000000000 --- a/src/qt/scicon.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2014 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_QT_SCICON_H -#define BITCOIN_QT_SCICON_H - -#include <QtCore> - -QT_BEGIN_NAMESPACE -class QColor; -class QIcon; -class QString; -QT_END_NAMESPACE - -QImage SingleColorImage(const QString& filename, const QColor&); -QIcon SingleColorIcon(const QIcon&, const QColor&); -QIcon SingleColorIcon(const QString& filename, const QColor&); -QColor SingleColor(); -QIcon SingleColorIcon(const QString& filename); -QIcon TextColorIcon(const QIcon&); -QIcon TextColorIcon(const QString& filename); - -#endif // BITCOIN_QT_SCICON_H diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 0360f160d8..a083a6f80e 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -11,14 +11,15 @@ #include "coincontroldialog.h" #include "guiutil.h" #include "optionsmodel.h" -#include "scicon.h" +#include "platformstyle.h" #include "sendcoinsentry.h" #include "walletmodel.h" #include "base58.h" #include "coincontrol.h" -#include "main.h" +#include "main.h" // mempool and minRelayTxFee #include "ui_interface.h" +#include "txmempool.h" #include "wallet/wallet.h" #include <QMessageBox> @@ -26,25 +27,26 @@ #include <QSettings> #include <QTextDocument> -SendCoinsDialog::SendCoinsDialog(QWidget *parent) : +SendCoinsDialog::SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::SendCoinsDialog), clientModel(0), model(0), fNewRecipientAllowed(true), - fFeeMinimized(true) + fFeeMinimized(true), + platformStyle(platformStyle) { ui->setupUi(this); -#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac - ui->addButton->setIcon(QIcon()); - ui->clearButton->setIcon(QIcon()); - ui->sendButton->setIcon(QIcon()); -#else - ui->addButton->setIcon(SingleColorIcon(":/icons/add")); - ui->clearButton->setIcon(SingleColorIcon(":/icons/remove")); - ui->sendButton->setIcon(SingleColorIcon(":/icons/send")); -#endif + if (!platformStyle->getImagesOnButtons()) { + ui->addButton->setIcon(QIcon()); + ui->clearButton->setIcon(QIcon()); + ui->sendButton->setIcon(QIcon()); + } else { + ui->addButton->setIcon(platformStyle->SingleColorIcon(":/icons/add")); + ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + ui->sendButton->setIcon(platformStyle->SingleColorIcon(":/icons/send")); + } GUIUtil::setupAddressWidget(ui->lineEditCoinControlChange, this); @@ -251,7 +253,7 @@ void SendCoinsDialog::on_sendButton_clicked() // Format confirmation message QStringList formatted; - foreach(const SendCoinsRecipient &rcp, currentTransaction.getRecipients()) + Q_FOREACH(const SendCoinsRecipient &rcp, currentTransaction.getRecipients()) { // generate bold amount string QString amount = "<b>" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount); @@ -305,14 +307,14 @@ void SendCoinsDialog::on_sendButton_clicked() questionString.append("<hr />"); CAmount totalAmount = currentTransaction.getTotalTransactionAmount() + txFee; QStringList alternativeUnits; - foreach(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) + Q_FOREACH(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) { if(u != model->getOptionsModel()->getDisplayUnit()) alternativeUnits.append(BitcoinUnits::formatHtmlWithUnit(u, totalAmount)); } - questionString.append(tr("Total Amount %1 (= %2)") + questionString.append(tr("Total Amount %1<span style='font-size:10pt;font-weight:normal;'><br />(=%2)</span>") .arg(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), totalAmount)) - .arg(alternativeUnits.join(" " + tr("or") + " "))); + .arg(alternativeUnits.join(" " + tr("or") + "<br />"))); QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"), questionString.arg(formatted.join("<br />")), @@ -363,7 +365,7 @@ void SendCoinsDialog::accept() SendCoinsEntry *SendCoinsDialog::addEntry() { - SendCoinsEntry *entry = new SendCoinsEntry(this); + SendCoinsEntry *entry = new SendCoinsEntry(platformStyle, this); entry->setModel(model); ui->entries->addWidget(entry); connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*))); @@ -505,7 +507,7 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn switch(sendCoinsReturn.status) { case WalletModel::InvalidAddress: - msgParams.first = tr("The recipient address is not valid, please recheck."); + msgParams.first = tr("The recipient address is not valid. Please recheck."); break; case WalletModel::InvalidAmount: msgParams.first = tr("The amount to pay must be larger than 0."); @@ -517,7 +519,7 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn msgParams.first = tr("The total exceeds your balance when the %1 transaction fee is included.").arg(msgArg); break; case WalletModel::DuplicateAddress: - msgParams.first = tr("Duplicate address found, can only send to each address once per send operation."); + msgParams.first = tr("Duplicate address found: addresses should only be used once each."); break; case WalletModel::TransactionCreationFailed: msgParams.first = tr("Transaction creation failed!"); @@ -540,7 +542,7 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn return; } - emit message(tr("Send Coins"), msgParams.first, msgParams.second); + Q_EMIT message(tr("Send Coins"), msgParams.first, msgParams.second); } void SendCoinsDialog::minimizeFeeSection(bool fMinimize) @@ -590,12 +592,12 @@ void SendCoinsDialog::updateGlobalFeeVariables() { if (ui->radioSmartFee->isChecked()) { - nTxConfirmTarget = (int)25 - (int)std::max(0, std::min(24, ui->sliderSmartFee->value())); + nTxConfirmTarget = defaultConfirmTarget - ui->sliderSmartFee->value(); payTxFee = CFeeRate(0); } else { - nTxConfirmTarget = 25; + nTxConfirmTarget = defaultConfirmTarget; payTxFee = CFeeRate(ui->customFee->value()); fPayAtLeastCustomFee = ui->radioCustomAtLeast->isChecked(); } @@ -629,7 +631,7 @@ void SendCoinsDialog::updateSmartFeeLabel() if(!model || !model->getOptionsModel()) return; - int nBlocksToConfirm = (int)25 - (int)std::max(0, std::min(24, ui->sliderSmartFee->value())); + int nBlocksToConfirm = defaultConfirmTarget - ui->sliderSmartFee->value(); CFeeRate feeRate = mempool.estimateFee(nBlocksToConfirm); if (feeRate <= CFeeRate(0)) // not enough data => minfee { @@ -710,7 +712,7 @@ void SendCoinsDialog::coinControlFeatureChanged(bool checked) // Coin Control: button inputs -> show actual coin control dialog void SendCoinsDialog::coinControlButtonClicked() { - CoinControlDialog dlg; + CoinControlDialog dlg(platformStyle); dlg.setModel(model); dlg.exec(); coinControlUpdateLabels(); @@ -752,10 +754,9 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text) } else // Valid address { - CPubKey pubkey; CKeyID keyid; addr.GetKeyID(keyid); - if (!model->getPubKey(keyid, pubkey)) // Unknown change address + if (!model->havePrivKey(keyid)) // Unknown change address { ui->labelCoinControlChangeLabel->setText(tr("Warning: Unknown change address")); } diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 14adb02573..391905ffcd 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -12,6 +12,7 @@ class ClientModel; class OptionsModel; +class PlatformStyle; class SendCoinsEntry; class SendCoinsRecipient; @@ -23,13 +24,15 @@ QT_BEGIN_NAMESPACE class QUrl; QT_END_NAMESPACE +const int defaultConfirmTarget = 25; + /** Dialog for sending bitcoins */ class SendCoinsDialog : public QDialog { Q_OBJECT public: - explicit SendCoinsDialog(QWidget *parent = 0); + explicit SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent = 0); ~SendCoinsDialog(); void setClientModel(ClientModel *clientModel); @@ -43,7 +46,7 @@ public: void pasteEntry(const SendCoinsRecipient &rv); bool handlePaymentRequest(const SendCoinsRecipient &recipient); -public slots: +public Q_SLOTS: void clear(); void reject(); void accept(); @@ -58,15 +61,16 @@ private: WalletModel *model; bool fNewRecipientAllowed; bool fFeeMinimized; + const PlatformStyle *platformStyle; // Process WalletModel::SendCoinsReturn and generate a pair consisting - // of a message and message flags for use in emit message(). + // of a message and message flags for use in Q_EMIT message(). // Additional parameter msgArg can be used via .arg(msgArg). void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg = QString()); void minimizeFeeSection(bool fMinimize); void updateFeeMinimizedLabel(); -private slots: +private Q_SLOTS: void on_sendButton_clicked(); void on_buttonChooseFee_clicked(); void on_buttonMinimizeFee_clicked(); @@ -91,7 +95,7 @@ private slots: void updateSmartFeeLabel(); void updateGlobalFeeVariables(); -signals: +Q_SIGNALS: // Fired when a message should be reported to the user void message(const QString &title, const QString &message, unsigned int style); }; diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index ea35ed1d53..44aa8ad1af 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -9,30 +9,30 @@ #include "addresstablemodel.h" #include "guiutil.h" #include "optionsmodel.h" -#include "scicon.h" +#include "platformstyle.h" #include "walletmodel.h" #include <QApplication> #include <QClipboard> -SendCoinsEntry::SendCoinsEntry(QWidget *parent) : +SendCoinsEntry::SendCoinsEntry(const PlatformStyle *platformStyle, QWidget *parent) : QStackedWidget(parent), ui(new Ui::SendCoinsEntry), - model(0) + model(0), + platformStyle(platformStyle) { ui->setupUi(this); - ui->addressBookButton->setIcon(SingleColorIcon(":/icons/address-book")); - ui->pasteButton->setIcon(SingleColorIcon(":/icons/editpaste")); - ui->deleteButton->setIcon(SingleColorIcon(":/icons/remove")); - ui->deleteButton_is->setIcon(SingleColorIcon(":/icons/remove")); - ui->deleteButton_s->setIcon(SingleColorIcon(":/icons/remove")); + ui->addressBookButton->setIcon(platformStyle->SingleColorIcon(":/icons/address-book")); + ui->pasteButton->setIcon(platformStyle->SingleColorIcon(":/icons/editpaste")); + ui->deleteButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + ui->deleteButton_is->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + ui->deleteButton_s->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); setCurrentWidget(ui->SendCoins); -#ifdef Q_OS_MAC - ui->payToLayout->setSpacing(4); -#endif + if (platformStyle->getUseExtraSpacing()) + ui->payToLayout->setSpacing(4); #if QT_VERSION >= 0x040700 ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book")); #endif @@ -65,7 +65,7 @@ void SendCoinsEntry::on_addressBookButton_clicked() { if(!model) return; - AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::SendingTab, this); + AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::SendingTab, this); dlg.setModel(model->getAddressTableModel()); if(dlg.exec()) { @@ -114,7 +114,7 @@ void SendCoinsEntry::clear() void SendCoinsEntry::deleteClicked() { - emit removeEntry(this); + Q_EMIT removeEntry(this); } bool SendCoinsEntry::validate() @@ -216,7 +216,7 @@ void SendCoinsEntry::setValue(const SendCoinsRecipient &value) ui->addAsLabel->clear(); ui->payTo->setText(recipient.address); // this may set a label from addressbook - if (!recipient.label.isEmpty()) // if a label had been set from the addressbook, dont overwrite with an empty label + if (!recipient.label.isEmpty()) // if a label had been set from the addressbook, don't overwrite with an empty label ui->addAsLabel->setText(recipient.label); ui->payAmount->setValue(recipient.amount); } diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index c2d1185bdd..107ab70158 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -10,6 +10,7 @@ #include <QStackedWidget> class WalletModel; +class PlatformStyle; namespace Ui { class SendCoinsEntry; @@ -25,7 +26,7 @@ class SendCoinsEntry : public QStackedWidget Q_OBJECT public: - explicit SendCoinsEntry(QWidget *parent = 0); + explicit SendCoinsEntry(const PlatformStyle *platformStyle, QWidget *parent = 0); ~SendCoinsEntry(); void setModel(WalletModel *model); @@ -45,15 +46,15 @@ public: void setFocus(); -public slots: +public Q_SLOTS: void clear(); -signals: +Q_SIGNALS: void removeEntry(SendCoinsEntry *entry); void payAmountChanged(); void subtractFeeFromAmountChanged(); -private slots: +private Q_SLOTS: void deleteClicked(); void on_payTo_textChanged(const QString &address); void on_addressBookButton_clicked(); @@ -64,6 +65,7 @@ private: SendCoinsRecipient recipient; Ui::SendCoinsEntry *ui; WalletModel *model; + const PlatformStyle *platformStyle; bool updateLabel(const QString &address); }; diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index ce166f3672..60e8e36ebe 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -7,7 +7,7 @@ #include "addressbookpage.h" #include "guiutil.h" -#include "scicon.h" +#include "platformstyle.h" #include "walletmodel.h" #include "base58.h" @@ -20,21 +20,22 @@ #include <QClipboard> -SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) : +SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::SignVerifyMessageDialog), - model(0) + model(0), + platformStyle(platformStyle) { ui->setupUi(this); - ui->addressBookButton_SM->setIcon(SingleColorIcon(":/icons/address-book")); - ui->pasteButton_SM->setIcon(SingleColorIcon(":/icons/editpaste")); - ui->copySignatureButton_SM->setIcon(SingleColorIcon(":/icons/editcopy")); - ui->signMessageButton_SM->setIcon(SingleColorIcon(":/icons/edit")); - ui->clearButton_SM->setIcon(SingleColorIcon(":/icons/remove")); - ui->addressBookButton_VM->setIcon(SingleColorIcon(":/icons/address-book")); - ui->verifyMessageButton_VM->setIcon(SingleColorIcon(":/icons/transaction_0")); - ui->clearButton_VM->setIcon(SingleColorIcon(":/icons/remove")); + ui->addressBookButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/address-book")); + ui->pasteButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/editpaste")); + ui->copySignatureButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/editcopy")); + ui->signMessageButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/edit")); + ui->clearButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + ui->addressBookButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/address-book")); + ui->verifyMessageButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/transaction_0")); + ui->clearButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); #if QT_VERSION >= 0x040700 ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature")); @@ -94,7 +95,7 @@ void SignVerifyMessageDialog::on_addressBookButton_SM_clicked() { if (model && model->getAddressTableModel()) { - AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this); + AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this); dlg.setModel(model->getAddressTableModel()); if (dlg.exec()) { @@ -148,12 +149,12 @@ void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() return; } - CDataStream ss(SER_GETHASH, 0); + CHashWriter ss(SER_GETHASH, 0); ss << strMessageMagic; ss << ui->messageIn_SM->document()->toPlainText().toStdString(); std::vector<unsigned char> vchSig; - if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig)) + if (!key.SignCompact(ss.GetHash(), vchSig)) { ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signing failed.") + QString("</nobr>")); @@ -185,7 +186,7 @@ void SignVerifyMessageDialog::on_addressBookButton_VM_clicked() { if (model && model->getAddressTableModel()) { - AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::SendingTab, this); + AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::SendingTab, this); dlg.setModel(model->getAddressTableModel()); if (dlg.exec()) { @@ -223,12 +224,12 @@ void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked() return; } - CDataStream ss(SER_GETHASH, 0); + CHashWriter ss(SER_GETHASH, 0); ss << strMessageMagic; ss << ui->messageIn_VM->document()->toPlainText().toStdString(); CPubKey pubkey; - if (!pubkey.RecoverCompact(Hash(ss.begin(), ss.end()), vchSig)) + if (!pubkey.RecoverCompact(ss.GetHash(), vchSig)) { ui->signatureIn_VM->setValid(false); ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h index 27807adc84..d651d5049b 100644 --- a/src/qt/signverifymessagedialog.h +++ b/src/qt/signverifymessagedialog.h @@ -7,6 +7,7 @@ #include <QDialog> +class PlatformStyle; class WalletModel; namespace Ui { @@ -18,7 +19,7 @@ class SignVerifyMessageDialog : public QDialog Q_OBJECT public: - explicit SignVerifyMessageDialog(QWidget *parent); + explicit SignVerifyMessageDialog(const PlatformStyle *platformStyle, QWidget *parent); ~SignVerifyMessageDialog(); void setModel(WalletModel *model); @@ -34,8 +35,9 @@ protected: private: Ui::SignVerifyMessageDialog *ui; WalletModel *model; + const PlatformStyle *platformStyle; -private slots: +private Q_SLOTS: /* sign message */ void on_addressBookButton_SM_clicked(); void on_pasteButton_SM_clicked(); diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 8430e017c1..c15b64c327 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -57,7 +57,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) QPainter pixPaint(&pixmap); pixPaint.setPen(QColor(100,100,100)); - // draw a slighly radial gradient + // draw a slightly radial gradient QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio); gradient.setColorAt(0, Qt::white); gradient.setColorAt(1, QColor(247,247,247)); diff --git a/src/qt/splashscreen.h b/src/qt/splashscreen.h index 84e4556dd8..29d16d4eae 100644 --- a/src/qt/splashscreen.h +++ b/src/qt/splashscreen.h @@ -27,7 +27,7 @@ protected: void paintEvent(QPaintEvent *event); void closeEvent(QCloseEvent *event); -public slots: +public Q_SLOTS: /** Slot to call finish() method as it's not defined as slot */ void slotFinish(QWidget *mainWin); diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index e2ec439b2e..fa5696325d 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -185,7 +185,8 @@ void PaymentServerTests::paymentServerTests() tempFile.open(); tempFile.write((const char*)randData, sizeof(randData)); tempFile.close(); - QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false); + // compares 50001 <= BIP70_MAX_PAYMENTREQUEST_SIZE == false + QCOMPARE(PaymentServer::verifySize(tempFile.size()), false); // Payment request with amount overflow (amount is set to 21000001 BTC): data = DecodeBase64(paymentrequest5_cert2_BASE64); @@ -195,7 +196,7 @@ void PaymentServerTests::paymentServerTests() QVERIFY(r.paymentRequest.IsInitialized()); // Extract address and amount from the request QList<std::pair<CScript, CAmount> > sendingTos = r.paymentRequest.getPayTo(); - foreach (const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) { + Q_FOREACH (const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) { CTxDestination dest; if (ExtractDestination(sendingTo.first, dest)) QCOMPARE(PaymentServer::verifyAmount(sendingTo.second), false); diff --git a/src/qt/test/paymentservertests.h b/src/qt/test/paymentservertests.h index c98bbf0833..71d61fcbe7 100644 --- a/src/qt/test/paymentservertests.h +++ b/src/qt/test/paymentservertests.h @@ -14,7 +14,7 @@ class PaymentServerTests : public QObject { Q_OBJECT -private slots: +private Q_SLOTS: void paymentServerTests(); }; @@ -25,7 +25,7 @@ class RecipientCatcher : public QObject { Q_OBJECT -public slots: +public Q_SLOTS: void getRecipient(SendCoinsRecipient r); public: diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index bb768f1325..f91de2008c 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -17,6 +17,8 @@ #include <QObject> #include <QTest> +#include <openssl/ssl.h> + #if defined(QT_STATICPLUGIN) && QT_VERSION < 0x050000 #include <QtPlugin> Q_IMPORT_PLUGIN(qcncodecs) @@ -36,6 +38,8 @@ int main(int argc, char *argv[]) QCoreApplication app(argc, argv); app.setApplicationName("Bitcoin-Qt-test"); + SSL_library_init(); + URITests test1; if (QTest::qExec(&test1) != 0) fInvalid = true; diff --git a/src/qt/test/uritests.h b/src/qt/test/uritests.h index a0b7dc6c72..434169dcde 100644 --- a/src/qt/test/uritests.h +++ b/src/qt/test/uritests.h @@ -12,7 +12,7 @@ class URITests : public QObject { Q_OBJECT -private slots: +private Q_SLOTS: void uriTests(); }; diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index 0b2eb9eaf2..9b67445bc0 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -139,10 +139,10 @@ void TrafficGraphWidget::updateRates() } float tmax = 0.0f; - foreach(float f, vSamplesIn) { + Q_FOREACH(float f, vSamplesIn) { if(f > tmax) tmax = f; } - foreach(float f, vSamplesOut) { + Q_FOREACH(float f, vSamplesOut) { if(f > tmax) tmax = f; } fMax = tmax; diff --git a/src/qt/trafficgraphwidget.h b/src/qt/trafficgraphwidget.h index 4c6b17fe7e..6336a8d144 100644 --- a/src/qt/trafficgraphwidget.h +++ b/src/qt/trafficgraphwidget.h @@ -27,7 +27,7 @@ public: protected: void paintEvent(QPaintEvent *); -public slots: +public Q_SLOTS: void updateRates(); void setGraphRangeMins(int mins); void clear(); diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 4fffd03adf..801c6c62d2 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -21,12 +21,10 @@ #include <stdint.h> #include <string> -using namespace std; - QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx) { AssertLockHeld(cs_main); - if (!IsFinalTx(wtx, chainActive.Height() + 1)) + if (!CheckFinalTx(wtx)) { if (wtx.nLockTime < LOCKTIME_THRESHOLD) return tr("Open for %n more block(s)", "", wtx.nLockTime - chainActive.Height()); @@ -167,7 +165,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco if (fAllFromMe) { - if(fAllFromMe == ISMINE_WATCH_ONLY) + if(fAllFromMe & ISMINE_WATCH_ONLY) strHTML += "<b>" + tr("From") + ":</b> " + tr("watch-only") + "<br>"; // @@ -192,7 +190,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString()); if(toSelf == ISMINE_SPENDABLE) strHTML += " (own address)"; - else if(toSelf == ISMINE_WATCH_ONLY) + else if(toSelf & ISMINE_WATCH_ONLY) strHTML += " (watch-only)"; strHTML += "<br>"; } @@ -243,14 +241,14 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco strHTML += "<b>" + tr("Transaction ID") + ":</b> " + TransactionRecord::formatSubTxId(wtx.GetHash(), rec->idx) + "<br>"; // Message from normal bitcoin:URI (bitcoin:123...?message=example) - foreach (const PAIRTYPE(string, string)& r, wtx.vOrderForm) + Q_FOREACH (const PAIRTYPE(std::string, std::string)& r, wtx.vOrderForm) if (r.first == "Message") strHTML += "<br><b>" + tr("Message") + ":</b><br>" + GUIUtil::HtmlEscape(r.second, true) + "<br>"; // // PaymentRequest info: // - foreach (const PAIRTYPE(string, string)& r, wtx.vOrderForm) + Q_FOREACH (const PAIRTYPE(std::string, std::string)& r, wtx.vOrderForm) { if (r.first == "PaymentRequest") { diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 7f1db58e5d..d8623daf5d 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -56,7 +56,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * CTxDestination address; sub.idx = parts.size(); // sequence number sub.credit = txout.nValue; - sub.involvesWatchAddress = mine == ISMINE_WATCH_ONLY; + sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY; if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) { // Received by Bitcoin Address @@ -86,7 +86,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * BOOST_FOREACH(const CTxIn& txin, wtx.vin) { isminetype mine = wallet->IsMine(txin); - if(mine == ISMINE_WATCH_ONLY) involvesWatchAddress = true; + if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; if(fAllFromMe > mine) fAllFromMe = mine; } @@ -94,7 +94,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * BOOST_FOREACH(const CTxOut& txout, wtx.vout) { isminetype mine = wallet->IsMine(txout); - if(mine == ISMINE_WATCH_ONLY) involvesWatchAddress = true; + if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; if(fAllToMe > mine) fAllToMe = mine; } @@ -188,7 +188,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) status.depth = wtx.GetDepthInMainChain(); status.cur_num_blocks = chainActive.Height(); - if (!IsFinalTx(wtx, chainActive.Height() + 1)) + if (!CheckFinalTx(wtx)) { if (wtx.nLockTime < LOCKTIME_THRESHOLD) { diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 34464b4075..98ad1a44b6 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -8,7 +8,7 @@ #include "guiconstants.h" #include "guiutil.h" #include "optionsmodel.h" -#include "scicon.h" +#include "platformstyle.h" #include "transactiondesc.h" #include "transactionrecord.h" #include "walletmodel.h" @@ -25,6 +25,8 @@ #include <QIcon> #include <QList> +#include <boost/foreach.hpp> + // Amount column is right-aligned it contains numbers static int column_alignments[] = { Qt::AlignLeft|Qt::AlignVCenter, /* status */ @@ -142,7 +144,7 @@ public: { parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1); int insert_idx = lowerIndex; - foreach(const TransactionRecord &rec, toInsert) + Q_FOREACH(const TransactionRecord &rec, toInsert) { cachedWallet.insert(insert_idx, rec); insert_idx += 1; @@ -220,12 +222,13 @@ public: } }; -TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *parent): +TransactionTableModel::TransactionTableModel(const PlatformStyle *platformStyle, CWallet* wallet, WalletModel *parent): QAbstractTableModel(parent), wallet(wallet), walletModel(parent), priv(new TransactionTablePriv(wallet, this)), - fProcessingQueuedTransactions(false) + fProcessingQueuedTransactions(false), + platformStyle(platformStyle) { columns << QString() << QString() << tr("Date") << tr("Type") << tr("Label") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit()); priv->refreshWallet(); @@ -245,7 +248,7 @@ TransactionTableModel::~TransactionTableModel() void TransactionTableModel::updateAmountColumnTitle() { columns[Amount] = BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit()); - emit headerDataChanged(Qt::Horizontal,Amount,Amount); + Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount); } void TransactionTableModel::updateTransaction(const QString &hash, int status, bool showTransaction) @@ -262,8 +265,8 @@ void TransactionTableModel::updateConfirmations() // Invalidate status (number of confirmations) and (possibly) description // for all rows. Qt is smart enough to only actually request the data for the // visible rows. - emit dataChanged(index(0, Status), index(priv->size()-1, Status)); - emit dataChanged(index(0, ToAddress), index(priv->size()-1, ToAddress)); + Q_EMIT dataChanged(index(0, Status), index(priv->size()-1, Status)); + Q_EMIT dataChanged(index(0, ToAddress), index(priv->size()-1, ToAddress)); } int TransactionTableModel::rowCount(const QModelIndex &parent) const @@ -519,7 +522,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case Qt::DecorationRole: { QIcon icon = qvariant_cast<QIcon>(index.data(RawDecorationRole)); - return TextColorIcon(icon); + return platformStyle->TextColorIcon(icon); } case Qt::DisplayRole: switch(index.column()) @@ -650,7 +653,7 @@ void TransactionTableModel::updateDisplayUnit() { // emit dataChanged to update Amount column with the current unit updateAmountColumnTitle(); - emit dataChanged(index(0, Amount), index(priv->size()-1, Amount)); + Q_EMIT dataChanged(index(0, Amount), index(priv->size()-1, Amount)); } // queue notifications to show a non freezing progress dialog e.g. for rescan diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 30a15df9e6..2089f703a6 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -10,6 +10,7 @@ #include <QAbstractTableModel> #include <QStringList> +class PlatformStyle; class TransactionRecord; class TransactionTablePriv; class WalletModel; @@ -23,7 +24,7 @@ class TransactionTableModel : public QAbstractTableModel Q_OBJECT public: - explicit TransactionTableModel(CWallet* wallet, WalletModel *parent = 0); + explicit TransactionTableModel(const PlatformStyle *platformStyle, CWallet* wallet, WalletModel *parent = 0); ~TransactionTableModel(); enum ColumnIndex { @@ -82,6 +83,7 @@ private: QStringList columns; TransactionTablePriv *priv; bool fProcessingQueuedTransactions; + const PlatformStyle *platformStyle; void subscribeToCoreSignals(); void unsubscribeFromCoreSignals(); @@ -98,7 +100,7 @@ private: QVariant txWatchonlyDecoration(const TransactionRecord *wtx) const; QVariant txAddressDecoration(const TransactionRecord *wtx) const; -public slots: +public Q_SLOTS: /* New transaction, or transaction changed status */ void updateTransaction(const QString &hash, int status, bool showTransaction); void updateConfirmations(); diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 526940632e..54e5a82720 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -10,7 +10,7 @@ #include "editaddressdialog.h" #include "guiutil.h" #include "optionsmodel.h" -#include "scicon.h" +#include "platformstyle.h" #include "transactiondescdialog.h" #include "transactionfilterproxy.h" #include "transactionrecord.h" @@ -35,7 +35,7 @@ #include <QUrl> #include <QVBoxLayout> -TransactionView::TransactionView(QWidget *parent) : +TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent) : QWidget(parent), model(0), transactionProxyModel(0), transactionView(0) { @@ -44,27 +44,28 @@ TransactionView::TransactionView(QWidget *parent) : QHBoxLayout *hlayout = new QHBoxLayout(); hlayout->setContentsMargins(0,0,0,0); -#ifdef Q_OS_MAC - hlayout->setSpacing(5); - hlayout->addSpacing(26); -#else - hlayout->setSpacing(0); - hlayout->addSpacing(23); -#endif + + if (platformStyle->getUseExtraSpacing()) { + hlayout->setSpacing(5); + hlayout->addSpacing(26); + } else { + hlayout->setSpacing(0); + hlayout->addSpacing(23); + } watchOnlyWidget = new QComboBox(this); watchOnlyWidget->setFixedWidth(24); watchOnlyWidget->addItem("", TransactionFilterProxy::WatchOnlyFilter_All); - watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes); - watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No); + watchOnlyWidget->addItem(platformStyle->SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes); + watchOnlyWidget->addItem(platformStyle->SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No); hlayout->addWidget(watchOnlyWidget); dateWidget = new QComboBox(this); -#ifdef Q_OS_MAC - dateWidget->setFixedWidth(121); -#else - dateWidget->setFixedWidth(120); -#endif + if (platformStyle->getUseExtraSpacing()) { + dateWidget->setFixedWidth(121); + } else { + dateWidget->setFixedWidth(120); + } dateWidget->addItem(tr("All"), All); dateWidget->addItem(tr("Today"), Today); dateWidget->addItem(tr("This week"), ThisWeek); @@ -75,11 +76,11 @@ TransactionView::TransactionView(QWidget *parent) : hlayout->addWidget(dateWidget); typeWidget = new QComboBox(this); -#ifdef Q_OS_MAC - typeWidget->setFixedWidth(121); -#else - typeWidget->setFixedWidth(120); -#endif + if (platformStyle->getUseExtraSpacing()) { + typeWidget->setFixedWidth(121); + } else { + typeWidget->setFixedWidth(120); + } typeWidget->addItem(tr("All"), TransactionFilterProxy::ALL_TYPES); typeWidget->addItem(tr("Received with"), TransactionFilterProxy::TYPE(TransactionRecord::RecvWithAddress) | @@ -102,11 +103,11 @@ TransactionView::TransactionView(QWidget *parent) : #if QT_VERSION >= 0x040700 amountWidget->setPlaceholderText(tr("Min amount")); #endif -#ifdef Q_OS_MAC - amountWidget->setFixedWidth(97); -#else - amountWidget->setFixedWidth(100); -#endif + if (platformStyle->getUseExtraSpacing()) { + amountWidget->setFixedWidth(97); + } else { + amountWidget->setFixedWidth(100); + } amountWidget->setValidator(new QDoubleValidator(0, 1e20, 8, this)); hlayout->addWidget(amountWidget); @@ -121,11 +122,11 @@ TransactionView::TransactionView(QWidget *parent) : vlayout->setSpacing(0); int width = view->verticalScrollBar()->sizeHint().width(); // Cover scroll bar width with spacing -#ifdef Q_OS_MAC - hlayout->addSpacing(width+2); -#else - hlayout->addSpacing(width); -#endif + if (platformStyle->getUseExtraSpacing()) { + hlayout->addSpacing(width+2); + } else { + hlayout->addSpacing(width); + } // Always show scroll bar view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); view->setTabKeyNavigation(false); @@ -341,11 +342,11 @@ void TransactionView::exportClicked() writer.addColumn(tr("ID"), 0, TransactionTableModel::TxIDRole); if(!writer.write()) { - emit message(tr("Exporting Failed"), tr("There was an error trying to save the transaction history to %1.").arg(filename), + Q_EMIT message(tr("Exporting Failed"), tr("There was an error trying to save the transaction history to %1.").arg(filename), CClientUIInterface::MSG_ERROR); } else { - emit message(tr("Exporting Successful"), tr("The transaction history was successfully saved to %1.").arg(filename), + Q_EMIT message(tr("Exporting Successful"), tr("The transaction history was successfully saved to %1.").arg(filename), CClientUIInterface::MSG_INFORMATION); } } diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index 092d919042..ac157fb98d 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -10,6 +10,7 @@ #include <QWidget> #include <QKeyEvent> +class PlatformStyle; class TransactionFilterProxy; class WalletModel; @@ -32,7 +33,7 @@ class TransactionView : public QWidget Q_OBJECT public: - explicit TransactionView(QWidget *parent = 0); + explicit TransactionView(const PlatformStyle *platformStyle, QWidget *parent = 0); void setModel(WalletModel *model); @@ -83,7 +84,7 @@ private: bool eventFilter(QObject *obj, QEvent *event); -private slots: +private Q_SLOTS: void contextualMenu(const QPoint &); void dateRangeChanged(); void showDetails(); @@ -95,13 +96,13 @@ private slots: void openThirdPartyTxUrl(QString url); void updateWatchOnlyColumn(bool fHaveWatchOnly); -signals: +Q_SIGNALS: void doubleClicked(const QModelIndex&); /** Fired when a message should be reported to the user */ void message(const QString &title, const QString &message, unsigned int style); -public slots: +public Q_SLOTS: void chooseDate(int idx); void chooseType(int idx); void chooseWatchonly(int idx); diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 386cf31d73..5e26f3e01b 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -84,7 +84,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : QTextCharFormat bold; bold.setFontWeight(QFont::Bold); - foreach (const QString &line, coreOptions.split("\n")) { + Q_FOREACH (const QString &line, coreOptions.split("\n")) { if (line.startsWith(" -")) { cursor.currentTable()->appendRows(1); diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index 288b985f13..47282ae2d0 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -31,7 +31,7 @@ private: Ui::HelpMessageDialog *ui; QString text; -private slots: +private Q_SLOTS: void on_okButton_accepted(); }; diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index 892947bf3a..ba8c28464d 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -12,9 +12,10 @@ #include <QHBoxLayout> #include <QLabel> -WalletFrame::WalletFrame(BitcoinGUI *_gui) : +WalletFrame::WalletFrame(const PlatformStyle *platformStyle, BitcoinGUI *_gui) : QFrame(_gui), - gui(_gui) + gui(_gui), + platformStyle(platformStyle) { // Leave HBox hook for adding a list view later QHBoxLayout *walletFrameLayout = new QHBoxLayout(this); @@ -42,7 +43,7 @@ bool WalletFrame::addWallet(const QString& name, WalletModel *walletModel) if (!gui || !clientModel || !walletModel || mapWalletViews.count(name) > 0) return false; - WalletView *walletView = new WalletView(this); + WalletView *walletView = new WalletView(platformStyle, this); walletView->setBitcoinGUI(gui); walletView->setClientModel(clientModel); walletView->setWalletModel(walletModel); diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index eea97defc9..9a56e97f9c 100644 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -10,6 +10,7 @@ class BitcoinGUI; class ClientModel; +class PlatformStyle; class SendCoinsRecipient; class WalletModel; class WalletView; @@ -23,7 +24,7 @@ class WalletFrame : public QFrame Q_OBJECT public: - explicit WalletFrame(BitcoinGUI *_gui = 0); + explicit WalletFrame(const PlatformStyle *platformStyle, BitcoinGUI *_gui = 0); ~WalletFrame(); void setClientModel(ClientModel *clientModel); @@ -45,9 +46,11 @@ private: bool bOutOfSync; + const PlatformStyle *platformStyle; + WalletView *currentWalletView(); -public slots: +public Q_SLOTS: /** Switch to overview (home) page */ void gotoOverviewPage(); /** Switch to history (transactions) page */ diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 9b8be76beb..5c21db8bdf 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -25,9 +25,9 @@ #include <QSet> #include <QTimer> -using namespace std; +#include <boost/foreach.hpp> -WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) : +WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *wallet, OptionsModel *optionsModel, QObject *parent) : QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0), transactionTableModel(0), recentRequestsTableModel(0), @@ -39,7 +39,7 @@ WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *p fForceCheckBalanceChanged = false; addressTableModel = new AddressTableModel(wallet, this); - transactionTableModel = new TransactionTableModel(wallet, this); + transactionTableModel = new TransactionTableModel(platformStyle, wallet, this); recentRequestsTableModel = new RecentRequestsTableModel(wallet, this); // This timer will be fired repeatedly to update the balance @@ -107,7 +107,7 @@ void WalletModel::updateStatus() EncryptionStatus newEncryptionStatus = getEncryptionStatus(); if(cachedEncryptionStatus != newEncryptionStatus) - emit encryptionStatusChanged(newEncryptionStatus); + Q_EMIT encryptionStatusChanged(newEncryptionStatus); } void WalletModel::pollBalanceChanged() @@ -159,7 +159,7 @@ void WalletModel::checkBalanceChanged() cachedWatchOnlyBalance = newWatchOnlyBalance; cachedWatchUnconfBalance = newWatchUnconfBalance; cachedWatchImmatureBalance = newWatchImmatureBalance; - emit balanceChanged(newBalance, newUnconfirmedBalance, newImmatureBalance, + Q_EMIT balanceChanged(newBalance, newUnconfirmedBalance, newImmatureBalance, newWatchOnlyBalance, newWatchUnconfBalance, newWatchImmatureBalance); } } @@ -180,7 +180,7 @@ void WalletModel::updateAddressBook(const QString &address, const QString &label void WalletModel::updateWatchOnlyFlag(bool fHaveWatchonly) { fHaveWatchOnly = fHaveWatchonly; - emit notifyWatchonlyChanged(fHaveWatchonly); + Q_EMIT notifyWatchonlyChanged(fHaveWatchonly); } bool WalletModel::validateAddress(const QString &address) @@ -205,7 +205,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact int nAddresses = 0; // Pre-check input data for validity - foreach(const SendCoinsRecipient &rcp, recipients) + Q_FOREACH(const SendCoinsRecipient &rcp, recipients) { if (rcp.fSubtractFeeFromAmount) fSubtractFeeFromAmount = true; @@ -285,7 +285,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact { return SendCoinsReturn(AmountWithFeeExceedsBalance); } - emit message(tr("Send Coins"), QString::fromStdString(strFailReason), + Q_EMIT message(tr("Send Coins"), QString::fromStdString(strFailReason), CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } @@ -306,7 +306,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran LOCK2(cs_main, wallet->cs_wallet); CWalletTx *newTx = transaction.getTransaction(); - foreach(const SendCoinsRecipient &rcp, transaction.getRecipients()) + Q_FOREACH(const SendCoinsRecipient &rcp, transaction.getRecipients()) { if (rcp.paymentRequest.IsInitialized()) { @@ -337,7 +337,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran // Add addresses / update labels that we've sent to to the address book, // and emit coinsSent signal for each recipient - foreach(const SendCoinsRecipient &rcp, transaction.getRecipients()) + Q_FOREACH(const SendCoinsRecipient &rcp, transaction.getRecipients()) { // Don't touch the address book when we have a payment request if (!rcp.paymentRequest.IsInitialized()) @@ -361,7 +361,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran } } } - emit coinsSent(wallet, rcp, transaction_array); + Q_EMIT coinsSent(wallet, rcp, transaction_array); } checkBalanceChanged(); // update balance immediately, otherwise there could be a short noticeable delay until pollBalanceChanged hits @@ -521,7 +521,7 @@ WalletModel::UnlockContext WalletModel::requestUnlock() if(was_locked) { // Request UI to unlock wallet - emit requireUnlock(); + Q_EMIT requireUnlock(); } // If wallet is still locked, unlock was failed or cancelled, mark context as invalid bool valid = getEncryptionStatus() != Locked; @@ -556,6 +556,11 @@ bool WalletModel::getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const return wallet->GetPubKey(address, vchPubKeyOut); } +bool WalletModel::havePrivKey(const CKeyID &address) const +{ + return wallet->HaveKey(address); +} + // returns a list of COutputs from COutPoints void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs) { diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index e263438880..a5e877d81f 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -17,6 +17,7 @@ class AddressTableModel; class OptionsModel; +class PlatformStyle; class RecentRequestsTableModel; class TransactionTableModel; class WalletModelTransaction; @@ -100,7 +101,7 @@ class WalletModel : public QObject Q_OBJECT public: - explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0); + explicit WalletModel(const PlatformStyle *platformStyle, CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0); ~WalletModel(); enum StatusCode // Returned by sendCoins @@ -186,6 +187,7 @@ public: UnlockContext requestUnlock(); bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; + bool havePrivKey(const CKeyID &address) const; void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs); bool isSpent(const COutPoint& outpoint) const; void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const; @@ -227,7 +229,7 @@ private: void unsubscribeFromCoreSignals(); void checkBalanceChanged(); -signals: +Q_SIGNALS: // Signal that balance in wallet changed void balanceChanged(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance); @@ -252,7 +254,7 @@ signals: // Watch-only address added void notifyWatchonlyChanged(bool fHaveWatchonly); -public slots: +public Q_SLOTS: /* Wallet status might have changed */ void updateStatus(); /* New transaction, or transaction changed status */ diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 206bb7c774..6a9b2d5bd3 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -81,7 +81,7 @@ void WalletModelTransaction::reassignAmounts(int nChangePosRet) CAmount WalletModelTransaction::getTotalTransactionAmount() { CAmount totalTransactionAmount = 0; - foreach(const SendCoinsRecipient &rcp, recipients) + Q_FOREACH(const SendCoinsRecipient &rcp, recipients) { totalTransactionAmount += rcp.amount; } diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 956c8b8913..77efdb5cdd 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -11,8 +11,8 @@ #include "guiutil.h" #include "optionsmodel.h" #include "overviewpage.h" +#include "platformstyle.h" #include "receivecoinsdialog.h" -#include "scicon.h" #include "sendcoinsdialog.h" #include "signverifymessagedialog.h" #include "transactiontablemodel.h" @@ -29,31 +29,35 @@ #include <QPushButton> #include <QVBoxLayout> -WalletView::WalletView(QWidget *parent): +WalletView::WalletView(const PlatformStyle *platformStyle, QWidget *parent): QStackedWidget(parent), clientModel(0), - walletModel(0) + walletModel(0), + platformStyle(platformStyle) { // Create tabs - overviewPage = new OverviewPage(); + overviewPage = new OverviewPage(platformStyle); transactionsPage = new QWidget(this); QVBoxLayout *vbox = new QVBoxLayout(); QHBoxLayout *hbox_buttons = new QHBoxLayout(); - transactionView = new TransactionView(this); + transactionView = new TransactionView(platformStyle, this); vbox->addWidget(transactionView); QPushButton *exportButton = new QPushButton(tr("&Export"), this); exportButton->setToolTip(tr("Export the data in the current tab to a file")); -#ifndef Q_OS_MAC // Icons on push buttons are very uncommon on Mac - exportButton->setIcon(SingleColorIcon(":/icons/export")); -#endif + if (platformStyle->getImagesOnButtons()) { + exportButton->setIcon(platformStyle->SingleColorIcon(":/icons/export")); + } hbox_buttons->addStretch(); hbox_buttons->addWidget(exportButton); vbox->addLayout(hbox_buttons); transactionsPage->setLayout(vbox); - receiveCoinsPage = new ReceiveCoinsDialog(); - sendCoinsPage = new SendCoinsDialog(); + receiveCoinsPage = new ReceiveCoinsDialog(platformStyle); + sendCoinsPage = new SendCoinsDialog(platformStyle); + + usedSendingAddressesPage = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::SendingTab, this); + usedReceivingAddressesPage = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this); addWidget(overviewPage); addWidget(transactionsPage); @@ -114,6 +118,8 @@ void WalletView::setWalletModel(WalletModel *walletModel) overviewPage->setWalletModel(walletModel); receiveCoinsPage->setModel(walletModel); sendCoinsPage->setModel(walletModel); + usedReceivingAddressesPage->setModel(walletModel->getAddressTableModel()); + usedSendingAddressesPage->setModel(walletModel->getAddressTableModel()); if (walletModel) { @@ -153,7 +159,7 @@ void WalletView::processNewTransaction(const QModelIndex& parent, int start, int QString address = ttm->data(index, TransactionTableModel::AddressRole).toString(); QString label = ttm->data(index, TransactionTableModel::LabelRole).toString(); - emit incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label); + Q_EMIT incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label); } void WalletView::gotoOverviewPage() @@ -182,7 +188,7 @@ void WalletView::gotoSendCoinsPage(QString addr) void WalletView::gotoSignMessageTab(QString addr) { // calls show() in showTab_SM() - SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(this); + SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this); signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose); signVerifyMessageDialog->setModel(walletModel); signVerifyMessageDialog->showTab_SM(true); @@ -194,7 +200,7 @@ void WalletView::gotoSignMessageTab(QString addr) void WalletView::gotoVerifyMessageTab(QString addr) { // calls show() in showTab_VM() - SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(this); + SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this); signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose); signVerifyMessageDialog->setModel(walletModel); signVerifyMessageDialog->showTab_VM(true); @@ -215,7 +221,7 @@ void WalletView::showOutOfSyncWarning(bool fShow) void WalletView::updateEncryptionStatus() { - emit encryptionStatusChanged(walletModel->getEncryptionStatus()); + Q_EMIT encryptionStatusChanged(walletModel->getEncryptionStatus()); } void WalletView::encryptWallet(bool status) @@ -239,11 +245,11 @@ void WalletView::backupWallet() return; if (!walletModel->backupWallet(filename)) { - emit message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to %1.").arg(filename), + Q_EMIT message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to %1.").arg(filename), CClientUIInterface::MSG_ERROR); } else { - emit message(tr("Backup Successful"), tr("The wallet data was successfully saved to %1.").arg(filename), + Q_EMIT message(tr("Backup Successful"), tr("The wallet data was successfully saved to %1.").arg(filename), CClientUIInterface::MSG_INFORMATION); } } @@ -272,20 +278,20 @@ void WalletView::usedSendingAddresses() { if(!walletModel) return; - AddressBookPage *dlg = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab, this); - dlg->setAttribute(Qt::WA_DeleteOnClose); - dlg->setModel(walletModel->getAddressTableModel()); - dlg->show(); + + usedSendingAddressesPage->show(); + usedSendingAddressesPage->raise(); + usedSendingAddressesPage->activateWindow(); } void WalletView::usedReceivingAddresses() { if(!walletModel) return; - AddressBookPage *dlg = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this); - dlg->setAttribute(Qt::WA_DeleteOnClose); - dlg->setModel(walletModel->getAddressTableModel()); - dlg->show(); + + usedReceivingAddressesPage->show(); + usedReceivingAddressesPage->raise(); + usedReceivingAddressesPage->activateWindow(); } void WalletView::showProgress(const QString &title, int nProgress) diff --git a/src/qt/walletview.h b/src/qt/walletview.h index 1840e21e9c..2a6a6a2df2 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -12,11 +12,13 @@ class BitcoinGUI; class ClientModel; class OverviewPage; +class PlatformStyle; class ReceiveCoinsDialog; class SendCoinsDialog; class SendCoinsRecipient; class TransactionView; class WalletModel; +class AddressBookPage; QT_BEGIN_NAMESPACE class QModelIndex; @@ -34,7 +36,7 @@ class WalletView : public QStackedWidget Q_OBJECT public: - explicit WalletView(QWidget *parent); + explicit WalletView(const PlatformStyle *platformStyle, QWidget *parent); ~WalletView(); void setBitcoinGUI(BitcoinGUI *gui); @@ -60,12 +62,15 @@ private: QWidget *transactionsPage; ReceiveCoinsDialog *receiveCoinsPage; SendCoinsDialog *sendCoinsPage; + AddressBookPage *usedSendingAddressesPage; + AddressBookPage *usedReceivingAddressesPage; TransactionView *transactionView; QProgressDialog *progressDialog; + const PlatformStyle *platformStyle; -public slots: +public Q_SLOTS: /** Switch to overview (home) page */ void gotoOverviewPage(); /** Switch to history (transactions) page */ @@ -105,7 +110,7 @@ public slots: /** Show progress dialog e.g. for rescan */ void showProgress(const QString &title, int nProgress); -signals: +Q_SIGNALS: /** Signal that we want to show the main window */ void showNormalIfMinimized(); /** Fired when a message should be reported to the user */ diff --git a/src/rest.cpp b/src/rest.cpp index adc2d56284..226e237fc6 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -3,19 +3,26 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "chain.h" #include "primitives/block.h" #include "primitives/transaction.h" #include "main.h" +#include "httpserver.h" #include "rpcserver.h" #include "streams.h" #include "sync.h" +#include "txmempool.h" #include "utilstrencodings.h" #include "version.h" #include <boost/algorithm/string.hpp> +#include <boost/dynamic_bitset.hpp> + +#include "univalue/univalue.h" using namespace std; -using namespace json_spirit; + +static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once enum RetFormat { RF_UNDEF, @@ -34,33 +41,54 @@ static const struct { {RF_JSON, "json"}, }; -class RestErr -{ -public: - enum HTTPStatusCode status; - string message; +struct CCoin { + uint32_t nTxVer; // Don't call this nVersion, that name has a special meaning inside IMPLEMENT_SERIALIZE + uint32_t nHeight; + CTxOut out; + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) + { + READWRITE(nTxVer); + READWRITE(nHeight); + READWRITE(out); + } }; -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry); -extern Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); +extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); +extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); +extern UniValue mempoolInfoToJSON(); +extern UniValue mempoolToJSON(bool fVerbose = false); +extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); +extern UniValue blockheaderToJSON(const CBlockIndex* blockindex); -static RestErr RESTERR(enum HTTPStatusCode status, string message) +static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, string message) { - RestErr re; - re.status = status; - re.message = message; - return re; + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(status, message + "\r\n"); + return false; } -static enum RetFormat ParseDataFormat(vector<string>& params, const string strReq) +static enum RetFormat ParseDataFormat(std::string& param, const std::string& strReq) { - boost::split(params, strReq, boost::is_any_of(".")); - if (params.size() > 1) { - for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++) - if (params[1] == rf_names[i].name) - return rf_names[i].rf; + const std::string::size_type pos = strReq.rfind('.'); + if (pos == std::string::npos) + { + param = strReq; + return rf_names[0].rf; } + param = strReq.substr(0, pos); + const std::string suff(strReq, pos + 1); + + for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++) + if (suff == rf_names[i].name) + return rf_names[i].rf; + + /* If no suffix is found, return original string. */ + param = strReq; return rf_names[0].rf; } @@ -89,36 +117,44 @@ static bool ParseHashStr(const string& strReq, uint256& v) return true; } -static bool rest_headers(AcceptedConnection* conn, - const std::string& strReq, - const std::map<std::string, std::string>& mapHeaders, - bool fRun) +static bool CheckWarmup(HTTPRequest* req) +{ + std::string statusmessage; + if (RPCIsInWarmup(&statusmessage)) + return RESTERR(req, HTTP_SERVICE_UNAVAILABLE, "Service temporarily unavailable: " + statusmessage); + return true; +} + +static bool rest_headers(HTTPRequest* req, + const std::string& strURIPart) { - vector<string> params; - const RetFormat rf = ParseDataFormat(params, strReq); + if (!CheckWarmup(req)) + return false; + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); vector<string> path; - boost::split(path, params[0], boost::is_any_of("/")); + boost::split(path, param, boost::is_any_of("/")); if (path.size() != 2) - throw RESTERR(HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers/<count>/<hash>.<ext>."); + return RESTERR(req, HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers/<count>/<hash>.<ext>."); long count = strtol(path[0].c_str(), NULL, 10); if (count < 1 || count > 2000) - throw RESTERR(HTTP_BAD_REQUEST, "Header count out of range: " + path[0]); + return RESTERR(req, HTTP_BAD_REQUEST, "Header count out of range: " + path[0]); string hashStr = path[1]; uint256 hash; if (!ParseHashStr(hashStr, hash)) - throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); + return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); - std::vector<CBlockHeader> headers; + std::vector<const CBlockIndex *> headers; headers.reserve(count); { LOCK(cs_main); BlockMap::const_iterator it = mapBlockIndex.find(hash); const CBlockIndex *pindex = (it != mapBlockIndex.end()) ? it->second : NULL; while (pindex != NULL && chainActive.Contains(pindex)) { - headers.push_back(pindex->GetBlockHeader()); + headers.push_back(pindex); if (headers.size() == (unsigned long)count) break; pindex = chainActive.Next(pindex); @@ -126,25 +162,36 @@ static bool rest_headers(AcceptedConnection* conn, } CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); - BOOST_FOREACH(const CBlockHeader &header, headers) { - ssHeader << header; + BOOST_FOREACH(const CBlockIndex *pindex, headers) { + ssHeader << pindex->GetBlockHeader(); } switch (rf) { case RF_BINARY: { string binaryHeader = ssHeader.str(); - conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryHeader.size(), "application/octet-stream") << binaryHeader << std::flush; + req->WriteHeader("Content-Type", "application/octet-stream"); + req->WriteReply(HTTP_OK, binaryHeader); return true; } case RF_HEX: { string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush; + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(HTTP_OK, strHex); + return true; + } + case RF_JSON: { + UniValue jsonHeaders(UniValue::VARR); + BOOST_FOREACH(const CBlockIndex *pindex, headers) { + jsonHeaders.push_back(blockheaderToJSON(pindex)); + } + string strJSON = jsonHeaders.write() + "\n"; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } - default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)"); } } @@ -152,30 +199,32 @@ static bool rest_headers(AcceptedConnection* conn, return true; // continue to process further HTTP reqs on this cxn } -static bool rest_block(AcceptedConnection* conn, - const std::string& strReq, - const std::map<std::string, std::string>& mapHeaders, - bool fRun, +static bool rest_block(HTTPRequest* req, + const std::string& strURIPart, bool showTxDetails) { - vector<string> params; - const RetFormat rf = ParseDataFormat(params, strReq); + if (!CheckWarmup(req)) + return false; + std::string hashStr; + const RetFormat rf = ParseDataFormat(hashStr, strURIPart); - string hashStr = params[0]; uint256 hash; if (!ParseHashStr(hashStr, hash)) - throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); + return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); CBlock block; CBlockIndex* pblockindex = NULL; { LOCK(cs_main); if (mapBlockIndex.count(hash) == 0) - throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found"); + return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); pblockindex = mapBlockIndex[hash]; + if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) + return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); + if (!ReadBlockFromDisk(block, pblockindex)) - throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found"); + return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); @@ -184,25 +233,28 @@ static bool rest_block(AcceptedConnection* conn, switch (rf) { case RF_BINARY: { string binaryBlock = ssBlock.str(); - conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryBlock.size(), "application/octet-stream") << binaryBlock << std::flush; + req->WriteHeader("Content-Type", "application/octet-stream"); + req->WriteReply(HTTP_OK, binaryBlock); return true; } case RF_HEX: { string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush; + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(HTTP_OK, strHex); return true; } case RF_JSON: { - Object objBlock = blockToJSON(block, pblockindex, showTxDetails); - string strJSON = write_string(Value(objBlock), false) + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + UniValue objBlock = blockToJSON(block, pblockindex, showTxDetails); + string strJSON = objBlock.write() + "\n"; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); } } @@ -210,65 +262,106 @@ static bool rest_block(AcceptedConnection* conn, return true; // continue to process further HTTP reqs on this cxn } -static bool rest_block_extended(AcceptedConnection* conn, - const std::string& strReq, - const std::map<std::string, std::string>& mapHeaders, - bool fRun) +static bool rest_block_extended(HTTPRequest* req, const std::string& strURIPart) { - return rest_block(conn, strReq, mapHeaders, fRun, true); + return rest_block(req, strURIPart, true); } -static bool rest_block_notxdetails(AcceptedConnection* conn, - const std::string& strReq, - const std::map<std::string, std::string>& mapHeaders, - bool fRun) +static bool rest_block_notxdetails(HTTPRequest* req, const std::string& strURIPart) { - return rest_block(conn, strReq, mapHeaders, fRun, false); + return rest_block(req, strURIPart, false); } -static bool rest_chaininfo(AcceptedConnection* conn, - const std::string& strReq, - const std::map<std::string, std::string>& mapHeaders, - bool fRun) +static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart) { - vector<string> params; - const RetFormat rf = ParseDataFormat(params, strReq); - + if (!CheckWarmup(req)) + return false; + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); + switch (rf) { case RF_JSON: { - Array rpcParams; - Value chainInfoObject = getblockchaininfo(rpcParams, false); - - string strJSON = write_string(chainInfoObject, false) + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + UniValue rpcParams(UniValue::VARR); + UniValue chainInfoObject = getblockchaininfo(rpcParams, false); + string strJSON = chainInfoObject.write() + "\n"; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)"); } } - + // not reached return true; // continue to process further HTTP reqs on this cxn } -static bool rest_tx(AcceptedConnection* conn, - const std::string& strReq, - const std::map<std::string, std::string>& mapHeaders, - bool fRun) +static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart) { - vector<string> params; - const RetFormat rf = ParseDataFormat(params, strReq); + if (!CheckWarmup(req)) + return false; + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); + + switch (rf) { + case RF_JSON: { + UniValue mempoolInfoObject = mempoolInfoToJSON(); + + string strJSON = mempoolInfoObject.write() + "\n"; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); + return true; + } + default: { + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)"); + } + } + + // not reached + return true; // continue to process further HTTP reqs on this cxn +} + +static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPart) +{ + if (!CheckWarmup(req)) + return false; + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); + + switch (rf) { + case RF_JSON: { + UniValue mempoolObject = mempoolToJSON(true); + + string strJSON = mempoolObject.write() + "\n"; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); + return true; + } + default: { + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)"); + } + } + + // not reached + return true; // continue to process further HTTP reqs on this cxn +} + +static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) +{ + if (!CheckWarmup(req)) + return false; + std::string hashStr; + const RetFormat rf = ParseDataFormat(hashStr, strURIPart); - string hashStr = params[0]; uint256 hash; if (!ParseHashStr(hashStr, hash)) - throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); + return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); CTransaction tx; uint256 hashBlock = uint256(); if (!GetTransaction(hash, tx, hashBlock, true)) - throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found"); + return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << tx; @@ -276,26 +369,225 @@ static bool rest_tx(AcceptedConnection* conn, switch (rf) { case RF_BINARY: { string binaryTx = ssTx.str(); - conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryTx.size(), "application/octet-stream") << binaryTx << std::flush; + req->WriteHeader("Content-Type", "application/octet-stream"); + req->WriteReply(HTTP_OK, binaryTx); return true; } case RF_HEX: { string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush; + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(HTTP_OK, strHex); return true; } case RF_JSON: { - Object objTx; + UniValue objTx(UniValue::VOBJ); TxToJSON(tx, hashBlock, objTx); - string strJSON = write_string(Value(objTx), false) + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + string strJSON = objTx.write() + "\n"; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); + return true; + } + + default: { + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); + } + } + + // not reached + return true; // continue to process further HTTP reqs on this cxn +} + +static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) +{ + if (!CheckWarmup(req)) + return false; + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); + + vector<string> uriParts; + if (param.length() > 1) + { + std::string strUriParams = param.substr(1); + boost::split(uriParts, strUriParams, boost::is_any_of("/")); + } + + // throw exception in case of a empty request + std::string strRequestMutable = req->ReadBody(); + if (strRequestMutable.length() == 0 && uriParts.size() == 0) + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + + bool fInputParsed = false; + bool fCheckMemPool = false; + vector<COutPoint> vOutPoints; + + // parse/deserialize input + // input-format = output-format, rest/getutxos/bin requires binary input, gives binary output, ... + + if (uriParts.size() > 0) + { + + //inputs is sent over URI scheme (/rest/getutxos/checkmempool/txid1-n/txid2-n/...) + if (uriParts.size() > 0 && uriParts[0] == "checkmempool") + fCheckMemPool = true; + + for (size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++) + { + uint256 txid; + int32_t nOutput; + std::string strTxid = uriParts[i].substr(0, uriParts[i].find("-")); + std::string strOutput = uriParts[i].substr(uriParts[i].find("-")+1); + + if (!ParseInt32(strOutput, &nOutput) || !IsHex(strTxid)) + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Parse error"); + + txid.SetHex(strTxid); + vOutPoints.push_back(COutPoint(txid, (uint32_t)nOutput)); + } + + if (vOutPoints.size() > 0) + fInputParsed = true; + else + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + } + + switch (rf) { + case RF_HEX: { + // convert hex to bin, continue then with bin part + std::vector<unsigned char> strRequestV = ParseHex(strRequestMutable); + strRequestMutable.assign(strRequestV.begin(), strRequestV.end()); + } + + case RF_BINARY: { + try { + //deserialize only if user sent a request + if (strRequestMutable.size() > 0) + { + if (fInputParsed) //don't allow sending input over URI and HTTP RAW DATA + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Combination of URI scheme inputs and raw post data is not allowed"); + + CDataStream oss(SER_NETWORK, PROTOCOL_VERSION); + oss << strRequestMutable; + oss >> fCheckMemPool; + oss >> vOutPoints; + } + } catch (const std::ios_base::failure& e) { + // abort in case of unreadable binary data + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Parse error"); + } + break; + } + + case RF_JSON: { + if (!fInputParsed) + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + break; + } + default: { + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); + } + } + + // limit max outpoints + if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS) + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size())); + + // check spentness and form a bitmap (as well as a JSON capable human-readble string representation) + vector<unsigned char> bitmap; + vector<CCoin> outs; + std::string bitmapStringRepresentation; + boost::dynamic_bitset<unsigned char> hits(vOutPoints.size()); + { + LOCK2(cs_main, mempool.cs); + + CCoinsView viewDummy; + CCoinsViewCache view(&viewDummy); + + CCoinsViewCache& viewChain = *pcoinsTip; + CCoinsViewMemPool viewMempool(&viewChain, mempool); + + if (fCheckMemPool) + view.SetBackend(viewMempool); // switch cache backend to db+mempool in case user likes to query mempool + + for (size_t i = 0; i < vOutPoints.size(); i++) { + CCoins coins; + uint256 hash = vOutPoints[i].hash; + if (view.GetCoins(hash, coins)) { + mempool.pruneSpent(hash, coins); + if (coins.IsAvailable(vOutPoints[i].n)) { + hits[i] = true; + // Safe to index into vout here because IsAvailable checked if it's off the end of the array, or if + // n is valid but points to an already spent output (IsNull). + CCoin coin; + coin.nTxVer = coins.nVersion; + coin.nHeight = coins.nHeight; + coin.out = coins.vout.at(vOutPoints[i].n); + assert(!coin.out.IsNull()); + outs.push_back(coin); + } + } + + bitmapStringRepresentation.append(hits[i] ? "1" : "0"); // form a binary string representation (human-readable for json output) + } + } + boost::to_block_range(hits, std::back_inserter(bitmap)); + + switch (rf) { + case RF_BINARY: { + // serialize data + // use exact same output as mentioned in Bip64 + CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION); + ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs; + string ssGetUTXOResponseString = ssGetUTXOResponse.str(); + + req->WriteHeader("Content-Type", "application/octet-stream"); + req->WriteReply(HTTP_OK, ssGetUTXOResponseString); + return true; + } + + case RF_HEX: { + CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION); + ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs; + string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n"; + + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(HTTP_OK, strHex); return true; } + case RF_JSON: { + UniValue objGetUTXOResponse(UniValue::VOBJ); + + // pack in some essentials + // use more or less the same output as mentioned in Bip64 + objGetUTXOResponse.push_back(Pair("chainHeight", chainActive.Height())); + objGetUTXOResponse.push_back(Pair("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex())); + objGetUTXOResponse.push_back(Pair("bitmap", bitmapStringRepresentation)); + + UniValue utxos(UniValue::VARR); + BOOST_FOREACH (const CCoin& coin, outs) { + UniValue utxo(UniValue::VOBJ); + utxo.push_back(Pair("txvers", (int32_t)coin.nTxVer)); + utxo.push_back(Pair("height", (int32_t)coin.nHeight)); + utxo.push_back(Pair("value", ValueFromAmount(coin.out.nValue))); + + // include the script in a json output + UniValue o(UniValue::VOBJ); + ScriptPubKeyToJSON(coin.out.scriptPubKey, o, true); + utxo.push_back(Pair("scriptPubKey", o)); + utxos.push_back(utxo); + } + objGetUTXOResponse.push_back(Pair("utxos", utxos)); + + // return json string + string strJSON = objGetUTXOResponse.write() + "\n"; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); + return true; + } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); } } @@ -305,40 +597,31 @@ static bool rest_tx(AcceptedConnection* conn, static const struct { const char* prefix; - bool (*handler)(AcceptedConnection* conn, - const std::string& strURI, - const std::map<std::string, std::string>& mapHeaders, - bool fRun); + bool (*handler)(HTTPRequest* req, const std::string& strReq); } uri_prefixes[] = { {"/rest/tx/", rest_tx}, {"/rest/block/notxdetails/", rest_block_notxdetails}, {"/rest/block/", rest_block_extended}, {"/rest/chaininfo", rest_chaininfo}, + {"/rest/mempool/info", rest_mempool_info}, + {"/rest/mempool/contents", rest_mempool_contents}, {"/rest/headers/", rest_headers}, + {"/rest/getutxos", rest_getutxos}, }; -bool HTTPReq_REST(AcceptedConnection* conn, - const std::string& strURI, - const std::map<std::string, std::string>& mapHeaders, - bool fRun) +bool StartREST() { - try { - std::string statusmessage; - if (RPCIsInWarmup(&statusmessage)) - throw RESTERR(HTTP_SERVICE_UNAVAILABLE, "Service temporarily unavailable: " + statusmessage); - - for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++) { - unsigned int plen = strlen(uri_prefixes[i].prefix); - if (strURI.substr(0, plen) == uri_prefixes[i].prefix) { - string strReq = strURI.substr(plen); - return uri_prefixes[i].handler(conn, strReq, mapHeaders, fRun); - } - } - } catch (const RestErr& re) { - conn->stream() << HTTPReply(re.status, re.message + "\r\n", false, false, "text/plain") << std::flush; - return false; - } + for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++) + RegisterHTTPHandler(uri_prefixes[i].prefix, false, uri_prefixes[i].handler); + return true; +} - conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush; - return false; +void InterruptREST() +{ +} + +void StopREST() +{ + for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++) + UnregisterHTTPHandler(uri_prefixes[i].prefix, false); } diff --git a/src/reverselock.h b/src/reverselock.h new file mode 100644 index 0000000000..567636e16a --- /dev/null +++ b/src/reverselock.h @@ -0,0 +1,31 @@ +// 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_REVERSELOCK_H +#define BITCOIN_REVERSELOCK_H + +/** + * An RAII-style reverse lock. Unlocks on construction and locks on destruction. + */ +template<typename Lock> +class reverse_lock +{ +public: + + explicit reverse_lock(Lock& lock) : lock(lock) { + lock.unlock(); + } + + ~reverse_lock() { + lock.lock(); + } + +private: + reverse_lock(reverse_lock const&); + reverse_lock& operator=(reverse_lock const&); + + Lock& lock; +}; + +#endif // BITCOIN_REVERSELOCK_H diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 293d6d5619..1c201ef99d 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -3,21 +3,29 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "amount.h" +#include "chain.h" +#include "chainparams.h" #include "checkpoints.h" +#include "coins.h" +#include "consensus/validation.h" #include "main.h" +#include "primitives/transaction.h" #include "rpcserver.h" +#include "streams.h" #include "sync.h" +#include "txmempool.h" #include "util.h" +#include "utilstrencodings.h" #include <stdint.h> -#include "json/json_spirit_value.h" +#include "univalue/univalue.h" -using namespace json_spirit; using namespace std; -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry); -void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex); +extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); +void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); double GetDifficulty(const CBlockIndex* blockindex) { @@ -50,10 +58,35 @@ double GetDifficulty(const CBlockIndex* blockindex) return dDiff; } +UniValue blockheaderToJSON(const CBlockIndex* blockindex) +{ + UniValue result(UniValue::VOBJ); + 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)) + confirmations = chainActive.Height() - blockindex->nHeight + 1; + result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("height", blockindex->nHeight)); + result.push_back(Pair("version", blockindex->nVersion)); + result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); + result.push_back(Pair("time", (int64_t)blockindex->nTime)); + result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce)); + result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits))); + result.push_back(Pair("difficulty", GetDifficulty(blockindex))); + result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); -Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) + if (blockindex->pprev) + result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + CBlockIndex *pnext = chainActive.Next(blockindex); + if (pnext) + result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + return result; +} + +UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("hash", block.GetHash().GetHex())); int confirmations = -1; // Only report confirmations if the block is on the main chain @@ -64,12 +97,12 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDe result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); - Array txs; + UniValue txs(UniValue::VARR); BOOST_FOREACH(const CTransaction&tx, block.vtx) { if(txDetails) { - Object objTx; + UniValue objTx(UniValue::VOBJ); TxToJSON(tx, uint256(), objTx); txs.push_back(objTx); } @@ -91,8 +124,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDe return result; } - -Value getblockcount(const Array& params, bool fHelp) +UniValue getblockcount(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -109,7 +141,7 @@ Value getblockcount(const Array& params, bool fHelp) return chainActive.Height(); } -Value getbestblockhash(const Array& params, bool fHelp) +UniValue getbestblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -126,7 +158,7 @@ Value getbestblockhash(const Array& params, bool fHelp) return chainActive.Tip()->GetBlockHash().GetHex(); } -Value getdifficulty(const Array& params, bool fHelp) +UniValue getdifficulty(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -143,8 +175,58 @@ Value getdifficulty(const Array& params, bool fHelp) return GetDifficulty(); } +UniValue mempoolToJSON(bool fVerbose = false) +{ + if (fVerbose) + { + LOCK(mempool.cs); + UniValue o(UniValue::VOBJ); + BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx) + { + 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("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.GetFeesWithDescendants())); + const CTransaction& tx = e.GetTx(); + set<string> 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); + } -Value getrawmempool(const Array& params, bool fHelp) + info.push_back(Pair("depends", depends)); + o.push_back(Pair(hash.ToString(), info)); + } + return o; + } + else + { + vector<uint256> vtxid; + mempool.queryHashes(vtxid); + + UniValue a(UniValue::VARR); + BOOST_FOREACH(const uint256& hash, vtxid) + a.push_back(hash.ToString()); + + return a; + } +} + +UniValue getrawmempool(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -161,16 +243,19 @@ Value getrawmempool(const Array& params, bool fHelp) "{ (json object)\n" " \"transactionid\" : { (json object)\n" " \"size\" : n, (numeric) transaction size in bytes\n" - " \"fee\" : n, (numeric) transaction fee in bitcoins\n" + " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\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) fees 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" - "]\n" + "}\n" "\nExamples\n" + HelpExampleCli("getrawmempool", "true") + HelpExampleRpc("getrawmempool", "true") @@ -182,48 +267,10 @@ Value getrawmempool(const Array& params, bool fHelp) if (params.size() > 0) fVerbose = params[0].get_bool(); - if (fVerbose) - { - LOCK(mempool.cs); - Object o; - BOOST_FOREACH(const PAIRTYPE(uint256, CTxMemPoolEntry)& entry, mempool.mapTx) - { - const uint256& hash = entry.first; - const CTxMemPoolEntry& e = entry.second; - Object info; - info.push_back(Pair("size", (int)e.GetTxSize())); - info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); - 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()))); - const CTransaction& tx = e.GetTx(); - set<string> setDepends; - BOOST_FOREACH(const CTxIn& txin, tx.vin) - { - if (mempool.exists(txin.prevout.hash)) - setDepends.insert(txin.prevout.hash.ToString()); - } - Array depends(setDepends.begin(), setDepends.end()); - info.push_back(Pair("depends", depends)); - o.push_back(Pair(hash.ToString(), info)); - } - return o; - } - else - { - vector<uint256> vtxid; - mempool.queryHashes(vtxid); - - Array a; - BOOST_FOREACH(const uint256& hash, vtxid) - a.push_back(hash.ToString()); - - return a; - } + return mempoolToJSON(fVerbose); } -Value getblockhash(const Array& params, bool fHelp) +UniValue getblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -248,7 +295,63 @@ Value getblockhash(const Array& params, bool fHelp) return pblockindex->GetBlockHash().GetHex(); } -Value getblock(const Array& params, bool fHelp) +UniValue getblockheader(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "getblockheader \"hash\" ( verbose )\n" + "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n" + "If verbose is true, returns an Object with information about blockheader <hash>.\n" + "\nArguments:\n" + "1. \"hash\" (string, required) The block hash\n" + "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n" + "\nResult (for verbose = true):\n" + "{\n" + " \"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" + " \"height\" : n, (numeric) The block height or index\n" + " \"version\" : n, (numeric) The block version\n" + " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" + " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"nonce\" : n, (numeric) The nonce\n" + " \"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" + "}\n" + "\nResult (for verbose=false):\n" + "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" + "\nExamples:\n" + + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + ); + + LOCK(cs_main); + + std::string strHash = params[0].get_str(); + uint256 hash(uint256S(strHash)); + + bool fVerbose = true; + if (params.size() > 1) + fVerbose = params[1].get_bool(); + + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlockIndex* pblockindex = mapBlockIndex[hash]; + + if (!fVerbose) + { + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + ssBlock << pblockindex->GetBlockHeader(); + std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); + return strHex; + } + + return blockheaderToJSON(pblockindex); +} + +UniValue getblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -299,6 +402,9 @@ Value getblock(const Array& params, bool fHelp) CBlock block; CBlockIndex* pblockindex = mapBlockIndex[hash]; + if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); + if(!ReadBlockFromDisk(block, pblockindex)) throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); @@ -313,7 +419,7 @@ Value getblock(const Array& params, bool fHelp) return blockToJSON(block, pblockindex); } -Value gettxoutsetinfo(const Array& params, bool fHelp) +UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -335,9 +441,7 @@ Value gettxoutsetinfo(const Array& params, bool fHelp) + HelpExampleRpc("gettxoutsetinfo", "") ); - LOCK(cs_main); - - Object ret; + UniValue ret(UniValue::VOBJ); CCoinsStats stats; FlushStateToDisk(); @@ -353,7 +457,7 @@ Value gettxoutsetinfo(const Array& params, bool fHelp) return ret; } -Value gettxout(const Array& params, bool fHelp) +UniValue gettxout(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 3) throw runtime_error( @@ -367,7 +471,7 @@ Value gettxout(const Array& params, bool fHelp) "{\n" " \"bestblock\" : \"hash\", (string) the block hash\n" " \"confirmations\" : n, (numeric) The number of confirmations\n" - " \"value\" : x.xxx, (numeric) The transaction value in btc\n" + " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n" " \"scriptPubKey\" : { (json object)\n" " \"asm\" : \"code\", (string) \n" " \"hex\" : \"hex\", (string) \n" @@ -393,7 +497,7 @@ Value gettxout(const Array& params, bool fHelp) LOCK(cs_main); - Object ret; + UniValue ret(UniValue::VOBJ); std::string strHash = params[0].get_str(); uint256 hash(uint256S(strHash)); @@ -407,14 +511,14 @@ Value gettxout(const Array& params, bool fHelp) LOCK(mempool.cs); CCoinsViewMemPool view(pcoinsTip, mempool); if (!view.GetCoins(hash, coins)) - return Value::null; + return NullUniValue; mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool } else { if (!pcoinsTip->GetCoins(hash, coins)) - return Value::null; + return NullUniValue; } if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull()) - return Value::null; + return NullUniValue; BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); CBlockIndex *pindex = it->second; @@ -424,7 +528,7 @@ Value gettxout(const Array& params, bool fHelp) else ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1)); ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue))); - Object o; + UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true); ret.push_back(Pair("scriptPubKey", o)); ret.push_back(Pair("version", coins.nVersion)); @@ -433,7 +537,7 @@ Value gettxout(const Array& params, bool fHelp) return ret; } -Value verifychain(const Array& params, bool fHelp) +UniValue verifychain(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 2) throw runtime_error( @@ -461,7 +565,37 @@ Value verifychain(const Array& params, bool fHelp) return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth); } -Value getblockchaininfo(const Array& params, bool fHelp) +/** Implementation of IsSuperMajority with better feedback */ +static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams) +{ + int nFound = 0; + CBlockIndex* pstart = pindex; + for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++) + { + if (pstart->nVersion >= minVersion) + ++nFound; + pstart = pstart->pprev; + } + + UniValue rv(UniValue::VOBJ); + rv.push_back(Pair("status", nFound >= nRequired)); + rv.push_back(Pair("found", nFound)); + rv.push_back(Pair("required", nRequired)); + rv.push_back(Pair("window", consensusParams.nMajorityWindow)); + return rv; +} + +static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams) +{ + UniValue rv(UniValue::VOBJ); + rv.push_back(Pair("id", name)); + rv.push_back(Pair("version", version)); + rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams))); + rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams))); + return rv; +} + +UniValue getblockchaininfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -476,6 +610,21 @@ Value getblockchaininfo(const Array& params, bool fHelp) " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" " \"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" + " \"softforks\": [ (array) status of softforks in progress\n" + " {\n" + " \"id\": \"xxxx\", (string) name of softfork\n" + " \"version\": xx, (numeric) block version\n" + " \"enforce\": { (object) progress toward enforcing the softfork rules for new-version blocks\n" + " \"status\": xx, (boolean) true if threshold reached\n" + " \"found\": xx, (numeric) number of blocks with the new version found\n" + " \"required\": xx, (numeric) number of blocks required to trigger\n" + " \"window\": xx, (numeric) maximum size of examined window of recent blocks\n" + " },\n" + " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n" + " }, ...\n" + " ]\n" "}\n" "\nExamples:\n" + HelpExampleCli("getblockchaininfo", "") @@ -484,14 +633,31 @@ Value getblockchaininfo(const Array& params, bool fHelp) LOCK(cs_main); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("chain", Params().NetworkIDString())); obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1)); obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex())); obj.push_back(Pair("difficulty", (double)GetDifficulty())); - obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(chainActive.Tip()))); + obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip()))); obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); + obj.push_back(Pair("pruned", fPruneMode)); + + const Consensus::Params& consensusParams = Params().GetConsensus(); + CBlockIndex* tip = chainActive.Tip(); + UniValue softforks(UniValue::VARR); + softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); + softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); + obj.push_back(Pair("softforks", softforks)); + + if (fPruneMode) + { + CBlockIndex *block = chainActive.Tip(); + while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) + block = block->pprev; + + obj.push_back(Pair("pruneheight", block->nHeight)); + } return obj; } @@ -510,7 +676,7 @@ struct CompareBlocksByHeight } }; -Value getchaintips(const Array& params, bool fHelp) +UniValue getchaintips(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -562,10 +728,10 @@ Value getchaintips(const Array& params, bool fHelp) setTips.insert(chainActive.Tip()); /* Construct the output array. */ - Array res; + UniValue res(UniValue::VARR); BOOST_FOREACH(const CBlockIndex* block, setTips) { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("height", block->nHeight)); obj.push_back(Pair("hash", block->phashBlock->GetHex())); @@ -600,7 +766,17 @@ Value getchaintips(const Array& params, bool fHelp) return res; } -Value getmempoolinfo(const Array& params, bool fHelp) +UniValue mempoolInfoToJSON() +{ + UniValue ret(UniValue::VOBJ); + ret.push_back(Pair("size", (int64_t) mempool.size())); + ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); + ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); + + return ret; +} + +UniValue getmempoolinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -610,20 +786,17 @@ Value getmempoolinfo(const Array& params, bool fHelp) "{\n" " \"size\": xxxxx (numeric) Current tx count\n" " \"bytes\": xxxxx (numeric) Sum of all tx sizes\n" + " \"usage\": xxxxx (numeric) Total memory usage for the mempool\n" "}\n" "\nExamples:\n" + HelpExampleCli("getmempoolinfo", "") + HelpExampleRpc("getmempoolinfo", "") ); - Object ret; - ret.push_back(Pair("size", (int64_t) mempool.size())); - ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); - - return ret; + return mempoolInfoToJSON(); } -Value invalidateblock(const Array& params, bool fHelp) +UniValue invalidateblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -658,10 +831,10 @@ Value invalidateblock(const Array& params, bool fHelp) throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); } - return Value::null; + return NullUniValue; } -Value reconsiderblock(const Array& params, bool fHelp) +UniValue reconsiderblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -697,5 +870,5 @@ Value reconsiderblock(const Array& params, bool fHelp) throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); } - return Value::null; + return NullUniValue; } diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 4b576b3707..0c8e6d6d66 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -11,8 +11,10 @@ #include <set> #include <stdint.h> +#include <boost/algorithm/string/case_conv.hpp> // for to_lower() +#include "univalue/univalue.h" + using namespace std; -using namespace json_spirit; class CRPCConvertParam { @@ -69,6 +71,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "listunspent", 1 }, { "listunspent", 2 }, { "getblock", 1 }, + { "getblockheader", 1 }, { "gettransaction", 1 }, { "getrawtransaction", 1 }, { "createrawtransaction", 0 }, @@ -76,6 +79,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "signrawtransaction", 1 }, { "signrawtransaction", 2 }, { "sendrawtransaction", 1 }, + { "fundrawtransaction", 1 }, { "gettxout", 1 }, { "gettxout", 2 }, { "gettxoutproof", 0 }, @@ -83,6 +87,8 @@ static const CRPCConvertParam vRPCConvertParams[] = { "lockunspent", 1 }, { "importprivkey", 2 }, { "importaddress", 2 }, + { "importaddress", 3 }, + { "importpubkey", 2 }, { "verifychain", 0 }, { "verifychain", 1 }, { "keypoolrefill", 0 }, @@ -91,6 +97,8 @@ static const CRPCConvertParam vRPCConvertParams[] = { "estimatepriority", 0 }, { "prioritisetransaction", 1 }, { "prioritisetransaction", 2 }, + { "setban", 2 }, + { "setban", 3 }, }; class CRPCConvertTable @@ -119,25 +127,32 @@ CRPCConvertTable::CRPCConvertTable() static CRPCConvertTable rpcCvtTable; +/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null) + * as well as objects and arrays. + */ +UniValue ParseNonRFCJSONValue(const std::string& strVal) +{ + UniValue jVal; + if (!jVal.read(std::string("[")+strVal+std::string("]")) || + !jVal.isArray() || jVal.size()!=1) + throw runtime_error(string("Error parsing JSON:")+strVal); + return jVal[0]; +} + /** Convert strings to command-specific RPC representation */ -Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams) +UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams) { - Array params; + UniValue params(UniValue::VARR); for (unsigned int idx = 0; idx < strParams.size(); idx++) { const std::string& strVal = strParams[idx]; - // insert string value directly if (!rpcCvtTable.convert(strMethod, idx)) { + // insert string value directly params.push_back(strVal); - } - - // parse string as JSON, insert bool/number/object/etc. value - else { - Value jVal; - if (!read_string(strVal, jVal)) - throw runtime_error(string("Error parsing JSON:")+strVal); - params.push_back(jVal); + } else { + // parse string as JSON, insert bool/number/object/etc. value + params.push_back(ParseNonRFCJSONValue(strVal)); } } diff --git a/src/rpcclient.h b/src/rpcclient.h index 42fa2d06fe..d68b4ed6ae 100644 --- a/src/rpcclient.h +++ b/src/rpcclient.h @@ -6,10 +6,12 @@ #ifndef BITCOIN_RPCCLIENT_H #define BITCOIN_RPCCLIENT_H -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" +#include "univalue/univalue.h" -json_spirit::Array RPCConvertValues(const std::string& strMethod, const std::vector<std::string>& strParams); +UniValue RPCConvertValues(const std::string& strMethod, const std::vector<std::string>& strParams); +/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null) + * as well as objects and arrays. + */ +UniValue ParseNonRFCJSONValue(const std::string& strVal); #endif // BITCOIN_RPCCLIENT_H diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 24b865150a..8dd0ff2f7e 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -4,8 +4,10 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "amount.h" +#include "chain.h" #include "chainparams.h" #include "consensus/consensus.h" +#include "consensus/validation.h" #include "core_io.h" #include "init.h" #include "main.h" @@ -13,21 +15,18 @@ #include "net.h" #include "pow.h" #include "rpcserver.h" +#include "txmempool.h" #include "util.h" +#include "utilstrencodings.h" #include "validationinterface.h" -#ifdef ENABLE_WALLET -#include "wallet/db.h" -#include "wallet/wallet.h" -#endif #include <stdint.h> #include <boost/assign/list_of.hpp> +#include <boost/shared_ptr.hpp> -#include "json/json_spirit_utils.h" -#include "json/json_spirit_value.h" +#include "univalue/univalue.h" -using namespace json_spirit; using namespace std; /** @@ -35,7 +34,7 @@ using namespace std; * or from the last difficulty change if 'lookup' is nonpositive. * If 'height' is nonnegative, compute the estimate at the time when a given block was found. */ -Value GetNetworkHashPS(int lookup, int height) { +UniValue GetNetworkHashPS(int lookup, int height) { CBlockIndex *pb = chainActive.Tip(); if (height >= 0 && height < chainActive.Height()) @@ -72,7 +71,7 @@ Value GetNetworkHashPS(int lookup, int height) { return (int64_t)(workDiff.getdouble() / timeDiff); } -Value getnetworkhashps(const Array& params, bool fHelp) +UniValue getnetworkhashps(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 2) throw runtime_error( @@ -94,8 +93,7 @@ Value getnetworkhashps(const Array& params, bool fHelp) return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1); } -#ifdef ENABLE_WALLET -Value getgenerate(const Array& params, bool fHelp) +UniValue getgenerate(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -114,14 +112,15 @@ Value getgenerate(const Array& params, bool fHelp) return GetBoolArg("-gen", false); } -Value generate(const Array& params, bool fHelp) +UniValue generate(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 1) 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" - "1. numblocks (numeric) How many blocks are generated immediately.\n" + "\nArguments:\n" + "1. numblocks (numeric, required) How many blocks are generated immediately.\n" "\nResult\n" "[ blockhashes ] (array) hashes of blocks generated\n" "\nExamples:\n" @@ -129,8 +128,6 @@ Value generate(const Array& params, bool fHelp) + HelpExampleCli("generate", "11") ); - if (pwalletMain == NULL) - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); if (!Params().MineBlocksOnDemand()) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest"); @@ -138,7 +135,17 @@ Value generate(const Array& params, bool fHelp) int nHeightEnd = 0; int nHeight = 0; int nGenerate = params[0].get_int(); - CReserveKey reservekey(pwalletMain); + + boost::shared_ptr<CReserveScript> 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); @@ -147,12 +154,12 @@ Value generate(const Array& params, bool fHelp) nHeightEnd = nHeightStart+nGenerate; } unsigned int nExtraNonce = 0; - Array blockHashes; + UniValue blockHashes(UniValue::VARR); while (nHeight < nHeightEnd) { - auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey)); + auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript)); if (!pblocktemplate.get()) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty"); + throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); CBlock *pblock = &pblocktemplate->block; { LOCK(cs_main); @@ -164,16 +171,18 @@ Value generate(const Array& params, bool fHelp) ++pblock->nNonce; } CValidationState state; - if (!ProcessNewBlock(state, NULL, pblock)) + if (!ProcessNewBlock(state, NULL, pblock, true, NULL)) throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); ++nHeight; blockHashes.push_back(pblock->GetHash().GetHex()); + + //mark script as important because it was used at least for one coinbase output + coinbaseScript->KeepScript(); } return blockHashes; } - -Value setgenerate(const Array& params, bool fHelp) +UniValue setgenerate(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -195,8 +204,6 @@ Value setgenerate(const Array& params, bool fHelp) + HelpExampleRpc("setgenerate", "true, 1") ); - if (pwalletMain == NULL) - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); if (Params().MineBlocksOnDemand()) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Use the generate method instead of setgenerate on this network"); @@ -214,14 +221,12 @@ Value setgenerate(const Array& params, bool fHelp) mapArgs["-gen"] = (fGenerate ? "1" : "0"); mapArgs ["-genproclimit"] = itostr(nGenProcLimit); - GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit); + GenerateBitcoins(fGenerate, nGenProcLimit, Params()); - return Value::null; + return NullUniValue; } -#endif - -Value getmininginfo(const Array& params, bool fHelp) +UniValue getmininginfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -248,7 +253,7 @@ Value getmininginfo(const Array& params, bool fHelp) LOCK(cs_main); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize)); obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); @@ -259,15 +264,13 @@ Value getmininginfo(const Array& params, bool fHelp) obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC())); obj.push_back(Pair("chain", Params().NetworkIDString())); -#ifdef ENABLE_WALLET obj.push_back(Pair("generate", getgenerate(params, false))); -#endif return obj; } // NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts -Value prioritisetransaction(const Array& params, bool fHelp) +UniValue prioritisetransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( @@ -299,10 +302,10 @@ Value prioritisetransaction(const Array& params, bool fHelp) // NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller -static Value BIP22ValidationResult(const CValidationState& state) +static UniValue BIP22ValidationResult(const CValidationState& state) { if (state.IsValid()) - return Value::null; + return NullUniValue; std::string strRejectReason = state.GetRejectReason(); if (state.IsError()) @@ -317,7 +320,7 @@ static Value BIP22ValidationResult(const CValidationState& state) return "valid?"; } -Value getblocktemplate(const Array& params, bool fHelp) +UniValue getblocktemplate(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -382,14 +385,14 @@ Value getblocktemplate(const Array& params, bool fHelp) LOCK(cs_main); std::string strMode = "template"; - Value lpval = Value::null; + UniValue lpval = NullUniValue; if (params.size() > 0) { - const Object& oparam = params[0].get_obj(); - const Value& modeval = find_value(oparam, "mode"); - if (modeval.type() == str_type) + const UniValue& oparam = params[0].get_obj(); + const UniValue& modeval = find_value(oparam, "mode"); + if (modeval.isStr()) strMode = modeval.get_str(); - else if (modeval.type() == null_type) + else if (modeval.isNull()) { /* Do nothing */ } @@ -399,8 +402,8 @@ Value getblocktemplate(const Array& params, bool fHelp) if (strMode == "proposal") { - const Value& dataval = find_value(oparam, "data"); - if (dataval.type() != str_type) + const UniValue& dataval = find_value(oparam, "data"); + if (!dataval.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); CBlock block; @@ -439,14 +442,14 @@ Value getblocktemplate(const Array& params, bool fHelp) static unsigned int nTransactionsUpdatedLast; - if (lpval.type() != null_type) + if (!lpval.isNull()) { // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions uint256 hashWatchedChain; boost::system_time checktxtime; unsigned int nTransactionsUpdatedLastLP; - if (lpval.type() == str_type) + if (lpval.isStr()) { // Format: <hashBestChain><nTransactionsUpdatedLast> std::string lpstr = lpval.get_str(); @@ -520,26 +523,25 @@ Value getblocktemplate(const Array& params, bool fHelp) UpdateTime(pblock, Params().GetConsensus(), pindexPrev); pblock->nNonce = 0; - static const Array aCaps = boost::assign::list_of("proposal"); + UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); - Array transactions; + UniValue transactions(UniValue::VARR); map<uint256, int64_t> setTxIndex; int i = 0; - BOOST_FOREACH (CTransaction& tx, pblock->vtx) - { + BOOST_FOREACH (const CTransaction& tx, pblock->vtx) { uint256 txHash = tx.GetHash(); setTxIndex[txHash] = i++; if (tx.IsCoinBase()) continue; - Object entry; + UniValue entry(UniValue::VOBJ); entry.push_back(Pair("data", EncodeHexTx(tx))); entry.push_back(Pair("hash", txHash.GetHex())); - Array deps; + UniValue deps(UniValue::VARR); BOOST_FOREACH (const CTxIn &in, tx.vin) { if (setTxIndex.count(in.prevout.hash)) @@ -554,12 +556,12 @@ Value getblocktemplate(const Array& params, bool fHelp) transactions.push_back(entry); } - Object aux; + UniValue aux(UniValue::VOBJ); aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); - static Array aMutable; + static UniValue aMutable(UniValue::VARR); if (aMutable.empty()) { aMutable.push_back("time"); @@ -567,7 +569,7 @@ Value getblocktemplate(const Array& params, bool fHelp) aMutable.push_back("prevblock"); } - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("capabilities", aCaps)); result.push_back(Pair("version", pblock->nVersion)); result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); @@ -606,7 +608,7 @@ protected: }; }; -Value submitblock(const Array& params, bool fHelp) +UniValue submitblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -650,7 +652,7 @@ Value submitblock(const Array& params, bool fHelp) CValidationState state; submitblock_StateCatcher sc(block.GetHash()); RegisterValidationInterface(&sc); - bool fAccepted = ProcessNewBlock(state, NULL, &block); + bool fAccepted = ProcessNewBlock(state, NULL, &block, true, NULL); UnregisterValidationInterface(&sc); if (fBlockPresent) { @@ -667,26 +669,25 @@ Value submitblock(const Array& params, bool fHelp) return BIP22ValidationResult(state); } -Value estimatefee(const Array& params, bool fHelp) +UniValue estimatefee(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( "estimatefee nblocks\n" - "\nEstimates the approximate fee per kilobyte\n" - "needed for a transaction to begin confirmation\n" - "within nblocks blocks.\n" + "\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n" + "confirmation within nblocks blocks.\n" "\nArguments:\n" "1. nblocks (numeric)\n" "\nResult:\n" - "n : (numeric) estimated fee-per-kilobyte\n" + "n (numeric) estimated fee-per-kilobyte\n" "\n" - "-1.0 is returned if not enough transactions and\n" - "blocks have been observed to make an estimate.\n" + "A negative value is returned if not enough transactions and blocks\n" + "have been observed to make an estimate.\n" "\nExample:\n" + HelpExampleCli("estimatefee", "6") ); - RPCTypeCheck(params, boost::assign::list_of(int_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); int nBlocks = params[0].get_int(); if (nBlocks < 1) @@ -699,26 +700,25 @@ Value estimatefee(const Array& params, bool fHelp) return ValueFromAmount(feeRate.GetFeePerK()); } -Value estimatepriority(const Array& params, bool fHelp) +UniValue estimatepriority(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( "estimatepriority nblocks\n" - "\nEstimates the approximate priority\n" - "a zero-fee transaction needs to begin confirmation\n" - "within nblocks blocks.\n" + "\nEstimates the approximate priority a zero-fee transaction needs to begin\n" + "confirmation within nblocks blocks.\n" "\nArguments:\n" "1. nblocks (numeric)\n" "\nResult:\n" - "n : (numeric) estimated priority\n" + "n (numeric) estimated priority\n" "\n" - "-1.0 is returned if not enough transactions and\n" - "blocks have been observed to make an estimate.\n" + "A negative value is returned if not enough transactions and blocks\n" + "have been observed to make an estimate.\n" "\nExample:\n" + HelpExampleCli("estimatepriority", "6") ); - RPCTypeCheck(params, boost::assign::list_of(int_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); int nBlocks = params[0].get_int(); if (nBlocks < 1) diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index f5bef2a077..e2b6d5826c 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -12,6 +12,7 @@ #include "rpcserver.h" #include "timedata.h" #include "util.h" +#include "utilstrencodings.h" #ifdef ENABLE_WALLET #include "wallet/wallet.h" #include "wallet/walletdb.h" @@ -20,10 +21,9 @@ #include <stdint.h> #include <boost/assign/list_of.hpp> -#include "json/json_spirit_utils.h" -#include "json/json_spirit_value.h" -using namespace json_spirit; +#include "univalue/univalue.h" + using namespace std; /** @@ -39,7 +39,7 @@ using namespace std; * * Or alternatively, create a specific query method for the information. **/ -Value getinfo(const Array& params, bool fHelp) +UniValue getinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -60,8 +60,8 @@ Value getinfo(const Array& params, bool fHelp) " \"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 set in btc/kb\n" - " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n" + " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in " + CURRENCY_UNIT + "/kB\n" + " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n" " \"errors\": \"...\" (string) any error messages\n" "}\n" "\nExamples:\n" @@ -78,7 +78,7 @@ Value getinfo(const Array& params, bool fHelp) proxyType proxy; GetProxy(NET_IPV4, proxy); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("version", CLIENT_VERSION)); obj.push_back(Pair("protocolversion", PROTOCOL_VERSION)); #ifdef ENABLE_WALLET @@ -108,41 +108,34 @@ Value getinfo(const Array& params, bool fHelp) } #ifdef ENABLE_WALLET -class DescribeAddressVisitor : public boost::static_visitor<Object> +class DescribeAddressVisitor : public boost::static_visitor<UniValue> { -private: - isminetype mine; - public: - DescribeAddressVisitor(isminetype mineIn) : mine(mineIn) {} + UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); } - Object operator()(const CNoDestination &dest) const { return Object(); } - - Object operator()(const CKeyID &keyID) const { - Object obj; + UniValue operator()(const CKeyID &keyID) const { + UniValue obj(UniValue::VOBJ); CPubKey vchPubKey; obj.push_back(Pair("isscript", false)); - if (mine == ISMINE_SPENDABLE) { - pwalletMain->GetPubKey(keyID, vchPubKey); + if (pwalletMain->GetPubKey(keyID, vchPubKey)) { obj.push_back(Pair("pubkey", HexStr(vchPubKey))); obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed())); } return obj; } - Object operator()(const CScriptID &scriptID) const { - Object obj; + UniValue operator()(const CScriptID &scriptID) const { + UniValue obj(UniValue::VOBJ); + CScript subscript; obj.push_back(Pair("isscript", true)); - if (mine != ISMINE_NO) { - CScript subscript; - pwalletMain->GetCScript(scriptID, subscript); + if (pwalletMain->GetCScript(scriptID, subscript)) { std::vector<CTxDestination> addresses; txnouttype whichType; int nRequired; ExtractDestinations(subscript, whichType, addresses, nRequired); obj.push_back(Pair("script", GetTxnOutputType(whichType))); obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end()))); - Array a; + UniValue a(UniValue::VARR); BOOST_FOREACH(const CTxDestination& addr, addresses) a.push_back(CBitcoinAddress(addr).ToString()); obj.push_back(Pair("addresses", a)); @@ -154,7 +147,7 @@ public: }; #endif -Value validateaddress(const Array& params, bool fHelp) +UniValue validateaddress(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -164,13 +157,14 @@ Value validateaddress(const Array& params, bool fHelp) "1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n" "\nResult:\n" "{\n" - " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n" + " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n" " \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n" " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n" - " \"ismine\" : true|false, (boolean) If the address is yours or not\n" - " \"isscript\" : true|false, (boolean) If the key is a script\n" + " \"ismine\" : true|false, (boolean) If the address is yours or not\n" + " \"iswatchonly\" : true|false, (boolean) If the address is watchonly\n" + " \"isscript\" : true|false, (boolean) If the key is a script\n" " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n" - " \"iscompressed\" : true|false, (boolean) If the address is compressed\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" "}\n" "\nExamples:\n" @@ -187,7 +181,7 @@ Value validateaddress(const Array& params, bool fHelp) CBitcoinAddress address(params[0].get_str()); bool isValid = address.IsValid(); - Object ret; + UniValue ret(UniValue::VOBJ); ret.push_back(Pair("isvalid", isValid)); if (isValid) { @@ -201,11 +195,9 @@ Value validateaddress(const Array& params, bool fHelp) #ifdef ENABLE_WALLET isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO; ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false)); - if (mine != ISMINE_NO) { - ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false)); - Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest); - ret.insert(ret.end(), detail.begin(), detail.end()); - } + ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false)); + UniValue detail = boost::apply_visitor(DescribeAddressVisitor(), dest); + ret.pushKVs(detail); if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name)); #endif @@ -216,10 +208,10 @@ Value validateaddress(const Array& params, bool fHelp) /** * Used by addmultisigaddress / createmultisig: */ -CScript _createmultisig_redeemScript(const Array& params) +CScript _createmultisig_redeemScript(const UniValue& params) { int nRequired = params[0].get_int(); - const Array& keys = params[1].get_array(); + const UniValue& keys = params[1].get_array(); // Gather public keys if (nRequired < 1) @@ -277,7 +269,7 @@ CScript _createmultisig_redeemScript(const Array& params) return result; } -Value createmultisig(const Array& params, bool fHelp) +UniValue createmultisig(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 2) { @@ -313,14 +305,14 @@ Value createmultisig(const Array& params, bool fHelp) CScriptID innerID(inner); CBitcoinAddress address(innerID); - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("address", address.ToString())); result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end()))); return result; } -Value verifymessage(const Array& params, bool fHelp) +UniValue verifymessage(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( @@ -374,7 +366,7 @@ Value verifymessage(const Array& params, bool fHelp) return (pubkey.GetID() == keyID); } -Value setmocktime(const Array& params, bool fHelp) +UniValue setmocktime(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -388,10 +380,19 @@ Value setmocktime(const Array& params, bool fHelp) if (!Params().MineBlocksOnDemand()) throw runtime_error("setmocktime for regression testing (-regtest mode) only"); - LOCK(cs_main); + // cs_vNodes is locked and node send/receive times are updated + // atomically with the time change to prevent peers from being + // disconnected because we think we haven't communicated with them + // in a long time. + LOCK2(cs_main, cs_vNodes); - RPCTypeCheck(params, boost::assign::list_of(int_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); SetMockTime(params[0].get_int64()); - return Value::null; + uint64_t t = GetTime(); + BOOST_FOREACH(CNode* pnode, vNodes) { + pnode->nLastSend = pnode->nLastRecv = t; + } + + return NullUniValue; } diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index bdee5b9f2e..5d490c70ca 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -4,6 +4,7 @@ #include "rpcserver.h" +#include "chainparams.h" #include "clientversion.h" #include "main.h" #include "net.h" @@ -11,17 +12,18 @@ #include "protocol.h" #include "sync.h" #include "timedata.h" +#include "ui_interface.h" #include "util.h" +#include "utilstrencodings.h" #include "version.h" #include <boost/foreach.hpp> -#include "json/json_spirit_value.h" +#include "univalue/univalue.h" -using namespace json_spirit; using namespace std; -Value getconnectioncount(const Array& params, bool fHelp) +UniValue getconnectioncount(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -39,7 +41,7 @@ Value getconnectioncount(const Array& params, bool fHelp) return (int)vNodes.size(); } -Value ping(const Array& params, bool fHelp) +UniValue ping(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -59,7 +61,7 @@ Value ping(const Array& params, bool fHelp) pNode->fPingQueued = true; } - return Value::null; + return NullUniValue; } static void CopyNodeStats(std::vector<CNodeStats>& vstats) @@ -75,7 +77,7 @@ static void CopyNodeStats(std::vector<CNodeStats>& vstats) } } -Value getpeerinfo(const Array& params, bool fHelp) +UniValue getpeerinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -95,6 +97,7 @@ Value getpeerinfo(const Array& params, bool fHelp) " \"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" " \"version\": v, (numeric) The peer version, such as 7001\n" " \"subver\": \"/Satoshi:0.8.5/\", (string) The string version\n" @@ -120,10 +123,10 @@ Value getpeerinfo(const Array& params, bool fHelp) vector<CNodeStats> vstats; CopyNodeStats(vstats); - Array ret; + UniValue ret(UniValue::VARR); BOOST_FOREACH(const CNodeStats& stats, vstats) { - Object obj; + UniValue obj(UniValue::VOBJ); CNodeStateStats statestats; bool fStateStats = GetNodeStateStats(stats.nodeid, statestats); obj.push_back(Pair("id", stats.nodeid)); @@ -138,6 +141,7 @@ Value getpeerinfo(const Array& params, bool fHelp) 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.dPingWait > 0.0) obj.push_back(Pair("pingwait", stats.dPingWait)); obj.push_back(Pair("version", stats.nVersion)); @@ -151,7 +155,7 @@ Value getpeerinfo(const Array& params, bool fHelp) obj.push_back(Pair("banscore", statestats.nMisbehavior)); obj.push_back(Pair("synced_headers", statestats.nSyncHeight)); obj.push_back(Pair("synced_blocks", statestats.nCommonHeight)); - Array heights; + UniValue heights(UniValue::VARR); BOOST_FOREACH(int height, statestats.vHeightInFlight) { heights.push_back(height); } @@ -165,7 +169,7 @@ Value getpeerinfo(const Array& params, bool fHelp) return ret; } -Value addnode(const Array& params, bool fHelp) +UniValue addnode(const UniValue& params, bool fHelp) { string strCommand; if (params.size() == 2) @@ -190,7 +194,7 @@ Value addnode(const Array& params, bool fHelp) { CAddress addr; OpenNetworkConnection(addr, NULL, strNode.c_str()); - return Value::null; + return NullUniValue; } LOCK(cs_vAddedNodes); @@ -212,10 +216,32 @@ Value addnode(const Array& params, bool fHelp) vAddedNodes.erase(it); } - return Value::null; + return NullUniValue; } -Value getaddednodeinfo(const Array& params, bool fHelp) +UniValue disconnectnode(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "disconnectnode \"node\" \n" + "\nImmediately disconnects from the specified node.\n" + "\nArguments:\n" + "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n" + "\nExamples:\n" + + HelpExampleCli("disconnectnode", "\"192.168.0.6:8333\"") + + HelpExampleRpc("disconnectnode", "\"192.168.0.6:8333\"") + ); + + CNode* pNode = FindNode(params[0].get_str()); + if (pNode == NULL) + throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes"); + + pNode->fDisconnect = true; + + return NullUniValue; +} + +UniValue getaddednodeinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -254,29 +280,29 @@ Value getaddednodeinfo(const Array& params, bool fHelp) if (params.size() == 1) { LOCK(cs_vAddedNodes); - BOOST_FOREACH(string& strAddNode, vAddedNodes) + BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) laddedNodes.push_back(strAddNode); } else { string strNode = params[1].get_str(); LOCK(cs_vAddedNodes); - BOOST_FOREACH(string& strAddNode, vAddedNodes) + BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) { if (strAddNode == strNode) { laddedNodes.push_back(strAddNode); break; } + } if (laddedNodes.size() == 0) throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added."); } - Array ret; + UniValue ret(UniValue::VARR); if (!fDns) { - BOOST_FOREACH(string& strAddNode, laddedNodes) - { - Object obj; + BOOST_FOREACH (const std::string& strAddNode, laddedNodes) { + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("addednode", strAddNode)); ret.push_back(obj); } @@ -284,17 +310,16 @@ Value getaddednodeinfo(const Array& params, bool fHelp) } list<pair<string, vector<CService> > > laddedAddreses(0); - BOOST_FOREACH(string& strAddNode, laddedNodes) - { + BOOST_FOREACH(const std::string& strAddNode, laddedNodes) { vector<CService> vservNode(0); if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0)) laddedAddreses.push_back(make_pair(strAddNode, vservNode)); else { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("addednode", strAddNode)); obj.push_back(Pair("connected", false)); - Array addresses; + UniValue addresses(UniValue::VARR); obj.push_back(Pair("addresses", addresses)); } } @@ -302,17 +327,16 @@ Value getaddednodeinfo(const Array& params, bool fHelp) LOCK(cs_vNodes); for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++) { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("addednode", it->first)); - Array addresses; + UniValue addresses(UniValue::VARR); bool fConnected = false; - BOOST_FOREACH(CService& addrNode, it->second) - { + BOOST_FOREACH(const CService& addrNode, it->second) { bool fFound = false; - Object node; + UniValue node(UniValue::VOBJ); node.push_back(Pair("address", addrNode.ToString())); - BOOST_FOREACH(CNode* pnode, vNodes) + BOOST_FOREACH(CNode* pnode, vNodes) { if (pnode->addr == addrNode) { fFound = true; @@ -320,6 +344,7 @@ Value getaddednodeinfo(const Array& params, bool fHelp) node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound")); break; } + } if (!fFound) node.push_back(Pair("connected", "false")); addresses.push_back(node); @@ -332,7 +357,7 @@ Value getaddednodeinfo(const Array& params, bool fHelp) return ret; } -Value getnettotals(const Array& params, bool fHelp) +UniValue getnettotals(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 0) throw runtime_error( @@ -350,23 +375,23 @@ Value getnettotals(const Array& params, bool fHelp) + HelpExampleRpc("getnettotals", "") ); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv())); obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent())); obj.push_back(Pair("timemillis", GetTimeMillis())); return obj; } -static Array GetNetworksInfo() +static UniValue GetNetworksInfo() { - Array networks; + UniValue networks(UniValue::VARR); for(int n=0; n<NET_MAX; ++n) { enum Network network = static_cast<enum Network>(n); if(network == NET_UNROUTABLE) continue; proxyType proxy; - Object obj; + UniValue obj(UniValue::VOBJ); GetProxy(network, proxy); obj.push_back(Pair("name", GetNetworkName(network))); obj.push_back(Pair("limited", IsLimited(network))); @@ -378,7 +403,7 @@ static Array GetNetworksInfo() return networks; } -Value getnetworkinfo(const Array& params, bool fHelp) +UniValue getnetworkinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -401,7 +426,7 @@ Value getnetworkinfo(const Array& params, bool fHelp) " }\n" " ,...\n" " ],\n" - " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n" + " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n" " \"localaddresses\": [ (array) list of local addresses\n" " {\n" " \"address\": \"xxxx\", (string) network address\n" @@ -410,6 +435,7 @@ Value getnetworkinfo(const Array& params, bool fHelp) " }\n" " ,...\n" " ]\n" + " \"warnings\": \"...\" (string) any network warnings (such as alert messages) \n" "}\n" "\nExamples:\n" + HelpExampleCli("getnetworkinfo", "") @@ -418,22 +444,21 @@ Value getnetworkinfo(const Array& params, bool fHelp) LOCK(cs_main); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("version", CLIENT_VERSION)); - obj.push_back(Pair("subversion", - FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()))); + 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("timeoffset", GetTimeOffset())); obj.push_back(Pair("connections", (int)vNodes.size())); obj.push_back(Pair("networks", GetNetworksInfo())); obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()))); - Array localAddresses; + UniValue localAddresses(UniValue::VARR); { LOCK(cs_mapLocalHost); BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost) { - Object rec; + UniValue rec(UniValue::VOBJ); rec.push_back(Pair("address", item.first.ToString())); rec.push_back(Pair("port", item.second.nPort)); rec.push_back(Pair("score", item.second.nScore)); @@ -441,5 +466,121 @@ Value getnetworkinfo(const Array& params, bool fHelp) } } obj.push_back(Pair("localaddresses", localAddresses)); + obj.push_back(Pair("warnings", GetWarnings("statusbar"))); return obj; } + +UniValue setban(const UniValue& params, bool fHelp) +{ + string strCommand; + if (params.size() >= 2) + strCommand = params[1].get_str(); + if (fHelp || params.size() < 2 || + (strCommand != "add" && strCommand != "remove")) + throw runtime_error( + "setban \"ip(/netmask)\" \"add|remove\" (bantime) (absolute)\n" + "\nAttempts add or remove a IP/Subnet from the banned list.\n" + "\nArguments:\n" + "1. \"ip(/netmask)\" (string, required) The IP/Subnet (see getpeerinfo for nodes ip) with a optional netmask (default is /32 = single ip)\n" + "2. \"command\" (string, required) 'add' to add a IP/Subnet to the list, 'remove' to remove a IP/Subnet from the list\n" + "3. \"bantime\" (numeric, optional) time in seconds how long (or until when if [absolute] is set) the ip is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument)\n" + "4. \"absolute\" (boolean, optional) If set, the bantime must be a absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n" + "\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") + ); + + CSubNet subNet; + CNetAddr netAddr; + bool isSubnet = false; + + if (params[0].get_str().find("/") != string::npos) + isSubnet = true; + + if (!isSubnet) + netAddr = CNetAddr(params[0].get_str()); + else + subNet = CSubNet(params[0].get_str()); + + if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) ) + throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Invalid IP/Subnet"); + + if (strCommand == "add") + { + if (isSubnet ? CNode::IsBanned(subNet) : CNode::IsBanned(netAddr)) + throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned"); + + int64_t banTime = 0; //use standard bantime if not specified + if (params.size() >= 3 && !params[2].isNull()) + banTime = params[2].get_int64(); + + bool absolute = false; + if (params.size() == 4 && params[3].isTrue()) + 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; +} + +UniValue listbanned(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "listbanned\n" + "\nList all banned IPs/Subnets.\n" + "\nExamples:\n" + + HelpExampleCli("listbanned", "") + + HelpExampleRpc("listbanned", "") + ); + + banmap_t banMap; + CNode::GetBanned(banMap); + + UniValue bannedAddresses(UniValue::VARR); + for (banmap_t::iterator it = banMap.begin(); it != banMap.end(); it++) + { + CBanEntry banEntry = (*it).second; + UniValue rec(UniValue::VOBJ); + rec.push_back(Pair("address", (*it).first.ToString())); + rec.push_back(Pair("banned_until", banEntry.nBanUntil)); + rec.push_back(Pair("ban_created", banEntry.nCreateTime)); + rec.push_back(Pair("ban_reason", banEntry.banReasonToString())); + + bannedAddresses.push_back(rec); + } + + return bannedAddresses; +} + +UniValue clearbanned(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "clearbanned\n" + "\nClear all banned IPs.\n" + "\nExamples:\n" + + HelpExampleCli("clearbanned", "") + + HelpExampleRpc("clearbanned", "") + ); + + CNode::ClearBanned(); + DumpBanlist(); //store banlist to disk + uiInterface.BannedListChanged(); + + return NullUniValue; +} diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index 95d6b9e531..d83cd87f94 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -5,7 +5,7 @@ #include "rpcprotocol.h" -#include "clientversion.h" +#include "random.h" #include "tinyformat.h" #include "util.h" #include "utilstrencodings.h" @@ -13,278 +13,115 @@ #include "version.h" #include <stdint.h> - -#include <boost/algorithm/string.hpp> -#include <boost/asio.hpp> -#include <boost/asio/ssl.hpp> -#include <boost/bind.hpp> -#include <boost/filesystem.hpp> -#include <boost/foreach.hpp> -#include <boost/iostreams/concepts.hpp> -#include <boost/iostreams/stream.hpp> -#include <boost/shared_ptr.hpp> -#include "json/json_spirit_writer_template.h" +#include <fstream> using namespace std; -using namespace json_spirit; - -//! Number of bytes to allocate and read at most at once in post data -const size_t POST_READ_SIZE = 256 * 1024; /** - * HTTP protocol + * JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility, + * but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were + * unspecified (HTTP errors and contents of 'error'). * - * This ain't Apache. We're just using HTTP header for the length field - * and to be compatible with other JSON-RPC implementations. + * 1.0 spec: http://json-rpc.org/wiki/specification + * 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html */ -string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeaders) +string JSONRPCRequest(const string& strMethod, const UniValue& params, const UniValue& id) { - ostringstream s; - s << "POST / HTTP/1.1\r\n" - << "User-Agent: bitcoin-json-rpc/" << FormatFullVersion() << "\r\n" - << "Host: 127.0.0.1\r\n" - << "Content-Type: application/json\r\n" - << "Content-Length: " << strMsg.size() << "\r\n" - << "Connection: close\r\n" - << "Accept: application/json\r\n"; - BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders) - s << item.first << ": " << item.second << "\r\n"; - s << "\r\n" << strMsg; - - return s.str(); + UniValue request(UniValue::VOBJ); + request.push_back(Pair("method", strMethod)); + request.push_back(Pair("params", params)); + request.push_back(Pair("id", id)); + return request.write() + "\n"; } -static string rfc1123Time() +UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id) { - return DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", GetTime()); + UniValue reply(UniValue::VOBJ); + if (!error.isNull()) + reply.push_back(Pair("result", NullUniValue)); + else + reply.push_back(Pair("result", result)); + reply.push_back(Pair("error", error)); + reply.push_back(Pair("id", id)); + return reply; } -static const char *httpStatusDescription(int nStatus) +string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id) { - switch (nStatus) { - case HTTP_OK: return "OK"; - case HTTP_BAD_REQUEST: return "Bad Request"; - case HTTP_FORBIDDEN: return "Forbidden"; - case HTTP_NOT_FOUND: return "Not Found"; - case HTTP_INTERNAL_SERVER_ERROR: return "Internal Server Error"; - default: return ""; - } + UniValue reply = JSONRPCReplyObj(result, error, id); + return reply.write() + "\n"; } -string HTTPError(int nStatus, bool keepalive, bool headersOnly) +UniValue JSONRPCError(int code, const string& message) { - if (nStatus == HTTP_UNAUTHORIZED) - return strprintf("HTTP/1.0 401 Authorization Required\r\n" - "Date: %s\r\n" - "Server: bitcoin-json-rpc/%s\r\n" - "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 296\r\n" - "\r\n" - "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n" - "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n" - "<HTML>\r\n" - "<HEAD>\r\n" - "<TITLE>Error</TITLE>\r\n" - "<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n" - "</HEAD>\r\n" - "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n" - "</HTML>\r\n", rfc1123Time(), FormatFullVersion()); - - return HTTPReply(nStatus, httpStatusDescription(nStatus), keepalive, - headersOnly, "text/plain"); + UniValue error(UniValue::VOBJ); + error.push_back(Pair("code", code)); + error.push_back(Pair("message", message)); + return error; } -string HTTPReplyHeader(int nStatus, bool keepalive, size_t contentLength, const char *contentType) -{ - return strprintf( - "HTTP/1.1 %d %s\r\n" - "Date: %s\r\n" - "Connection: %s\r\n" - "Content-Length: %u\r\n" - "Content-Type: %s\r\n" - "Server: bitcoin-json-rpc/%s\r\n" - "\r\n", - nStatus, - httpStatusDescription(nStatus), - rfc1123Time(), - keepalive ? "keep-alive" : "close", - contentLength, - contentType, - FormatFullVersion()); -} +/** Username used when cookie authentication is in use (arbitrary, only for + * recognizability in debugging/logging purposes) + */ +static const std::string COOKIEAUTH_USER = "__cookie__"; +/** Default name for auth cookie file */ +static const std::string COOKIEAUTH_FILE = ".cookie"; -string HTTPReply(int nStatus, const string& strMsg, bool keepalive, - bool headersOnly, const char *contentType) +boost::filesystem::path GetAuthCookieFile() { - if (headersOnly) - { - return HTTPReplyHeader(nStatus, keepalive, 0, contentType); - } else { - return HTTPReplyHeader(nStatus, keepalive, strMsg.size(), contentType) + strMsg; - } + boost::filesystem::path path(GetArg("-rpccookiefile", COOKIEAUTH_FILE)); + if (!path.is_complete()) path = GetDataDir() / path; + return path; } -bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto, - string& http_method, string& http_uri) +bool GenerateAuthCookie(std::string *cookie_out) { - string str; - getline(stream, str); - - // HTTP request line is space-delimited - vector<string> vWords; - boost::split(vWords, str, boost::is_any_of(" ")); - if (vWords.size() < 2) + unsigned char rand_pwd[32]; + GetRandBytes(rand_pwd, 32); + std::string cookie = COOKIEAUTH_USER + ":" + EncodeBase64(&rand_pwd[0],32); + + /** the umask determines what permissions are used to create this file - + * these are set to 077 in init.cpp unless overridden with -sysperms. + */ + std::ofstream file; + boost::filesystem::path filepath = GetAuthCookieFile(); + file.open(filepath.string().c_str()); + if (!file.is_open()) { + LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath.string()); return false; + } + file << cookie; + file.close(); + LogPrintf("Generated RPC authentication cookie %s\n", filepath.string()); - // HTTP methods permitted: GET, POST - http_method = vWords[0]; - if (http_method != "GET" && http_method != "POST") - return false; - - // HTTP URI must be an absolute path, relative to current host - http_uri = vWords[1]; - if (http_uri.size() == 0 || http_uri[0] != '/') - return false; - - // parse proto, if present - string strProto = ""; - if (vWords.size() > 2) - strProto = vWords[2]; - - proto = 0; - const char *ver = strstr(strProto.c_str(), "HTTP/1."); - if (ver != NULL) - proto = atoi(ver+7); - + if (cookie_out) + *cookie_out = cookie; return true; } -int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto) +bool GetAuthCookie(std::string *cookie_out) { - string str; - getline(stream, str); - vector<string> vWords; - boost::split(vWords, str, boost::is_any_of(" ")); - if (vWords.size() < 2) - return HTTP_INTERNAL_SERVER_ERROR; - proto = 0; - const char *ver = strstr(str.c_str(), "HTTP/1."); - if (ver != NULL) - proto = atoi(ver+7); - return atoi(vWords[1].c_str()); -} + std::ifstream file; + std::string cookie; + boost::filesystem::path filepath = GetAuthCookieFile(); + file.open(filepath.string().c_str()); + if (!file.is_open()) + return false; + std::getline(file, cookie); + file.close(); -int ReadHTTPHeaders(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet) -{ - int nLen = 0; - while (true) - { - string str; - std::getline(stream, str); - if (str.empty() || str == "\r") - break; - string::size_type nColon = str.find(":"); - if (nColon != string::npos) - { - string strHeader = str.substr(0, nColon); - boost::trim(strHeader); - boost::to_lower(strHeader); - string strValue = str.substr(nColon+1); - boost::trim(strValue); - mapHeadersRet[strHeader] = strValue; - if (strHeader == "content-length") - nLen = atoi(strValue.c_str()); - } - } - return nLen; + if (cookie_out) + *cookie_out = cookie; + return true; } - -int ReadHTTPMessage(std::basic_istream<char>& stream, map<string, - string>& mapHeadersRet, string& strMessageRet, - int nProto, size_t max_size) +void DeleteAuthCookie() { - mapHeadersRet.clear(); - strMessageRet = ""; - - // Read header - int nLen = ReadHTTPHeaders(stream, mapHeadersRet); - if (nLen < 0 || (size_t)nLen > max_size) - return HTTP_INTERNAL_SERVER_ERROR; - - // Read message - if (nLen > 0) - { - vector<char> vch; - size_t ptr = 0; - while (ptr < (size_t)nLen) - { - size_t bytes_to_read = std::min((size_t)nLen - ptr, POST_READ_SIZE); - vch.resize(ptr + bytes_to_read); - stream.read(&vch[ptr], bytes_to_read); - if (!stream) // Connection lost while reading - return HTTP_INTERNAL_SERVER_ERROR; - ptr += bytes_to_read; - } - strMessageRet = string(vch.begin(), vch.end()); - } - - string sConHdr = mapHeadersRet["connection"]; - - if ((sConHdr != "close") && (sConHdr != "keep-alive")) - { - if (nProto >= 1) - mapHeadersRet["connection"] = "keep-alive"; - else - mapHeadersRet["connection"] = "close"; + try { + boost::filesystem::remove(GetAuthCookieFile()); + } catch (const boost::filesystem::filesystem_error& e) { + LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__, e.what()); } - - return HTTP_OK; -} - -/** - * JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility, - * but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were - * unspecified (HTTP errors and contents of 'error'). - * - * 1.0 spec: http://json-rpc.org/wiki/specification - * 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html - * http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx - */ - -string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id) -{ - Object request; - request.push_back(Pair("method", strMethod)); - request.push_back(Pair("params", params)); - request.push_back(Pair("id", id)); - return write_string(Value(request), false) + "\n"; } -Object JSONRPCReplyObj(const Value& result, const Value& error, const Value& id) -{ - Object reply; - if (error.type() != null_type) - reply.push_back(Pair("result", Value::null)); - else - reply.push_back(Pair("result", result)); - reply.push_back(Pair("error", error)); - reply.push_back(Pair("id", id)); - return reply; -} - -string JSONRPCReply(const Value& result, const Value& error, const Value& id) -{ - Object reply = JSONRPCReplyObj(result, error, id); - return write_string(Value(reply), false) + "\n"; -} - -Object JSONRPCError(int code, const string& message) -{ - Object error; - error.push_back(Pair("code", code)); - error.push_back(Pair("message", message)); - return error; -} diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h index 4f3f70fb37..5381e4bcfd 100644 --- a/src/rpcprotocol.h +++ b/src/rpcprotocol.h @@ -10,14 +10,9 @@ #include <map> #include <stdint.h> #include <string> -#include <boost/iostreams/concepts.hpp> -#include <boost/iostreams/stream.hpp> -#include <boost/asio.hpp> -#include <boost/asio/ssl.hpp> +#include <boost/filesystem.hpp> -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" +#include "univalue/univalue.h" //! HTTP status codes enum HTTPStatusCode @@ -27,6 +22,7 @@ enum HTTPStatusCode HTTP_UNAUTHORIZED = 401, HTTP_FORBIDDEN = 403, HTTP_NOT_FOUND = 404, + HTTP_BAD_METHOD = 405, HTTP_INTERNAL_SERVER_ERROR = 500, HTTP_SERVICE_UNAVAILABLE = 503, }; @@ -65,6 +61,8 @@ enum RPCErrorCode 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.) @@ -78,91 +76,18 @@ enum RPCErrorCode RPC_WALLET_ALREADY_UNLOCKED = -17, //! Wallet is already unlocked }; -/** - * IOStream device that speaks SSL but can also speak non-SSL - */ -template <typename Protocol> -class SSLIOStreamDevice : public boost::iostreams::device<boost::iostreams::bidirectional> { -public: - SSLIOStreamDevice(boost::asio::ssl::stream<typename Protocol::socket> &streamIn, bool fUseSSLIn) : stream(streamIn) - { - fUseSSL = fUseSSLIn; - fNeedHandshake = fUseSSLIn; - } +std::string JSONRPCRequest(const std::string& strMethod, const UniValue& params, const UniValue& id); +UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id); +std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id); +UniValue JSONRPCError(int code, const std::string& message); - void handshake(boost::asio::ssl::stream_base::handshake_type role) - { - if (!fNeedHandshake) return; - fNeedHandshake = false; - stream.handshake(role); - } - std::streamsize read(char* s, std::streamsize n) - { - handshake(boost::asio::ssl::stream_base::server); // HTTPS servers read first - if (fUseSSL) return stream.read_some(boost::asio::buffer(s, n)); - return stream.next_layer().read_some(boost::asio::buffer(s, n)); - } - std::streamsize write(const char* s, std::streamsize n) - { - handshake(boost::asio::ssl::stream_base::client); // HTTPS clients write first - if (fUseSSL) return boost::asio::write(stream, boost::asio::buffer(s, n)); - return boost::asio::write(stream.next_layer(), boost::asio::buffer(s, n)); - } - bool connect(const std::string& server, const std::string& port) - { - using namespace boost::asio::ip; - tcp::resolver resolver(stream.get_io_service()); - tcp::resolver::iterator endpoint_iterator; -#if BOOST_VERSION >= 104300 - try { -#endif - // The default query (flags address_configured) tries IPv6 if - // non-localhost IPv6 configured, and IPv4 if non-localhost IPv4 - // configured. - tcp::resolver::query query(server.c_str(), port.c_str()); - endpoint_iterator = resolver.resolve(query); -#if BOOST_VERSION >= 104300 - } catch (const boost::system::system_error&) { - // If we at first don't succeed, try blanket lookup (IPv4+IPv6 independent of configured interfaces) - tcp::resolver::query query(server.c_str(), port.c_str(), resolver_query_base::flags()); - endpoint_iterator = resolver.resolve(query); - } -#endif - boost::system::error_code error = boost::asio::error::host_not_found; - tcp::resolver::iterator end; - while (error && endpoint_iterator != end) - { - stream.lowest_layer().close(); - stream.lowest_layer().connect(*endpoint_iterator++, error); - } - if (error) - return false; - return true; - } - -private: - bool fNeedHandshake; - bool fUseSSL; - boost::asio::ssl::stream<typename Protocol::socket>& stream; -}; - -std::string HTTPPost(const std::string& strMsg, const std::map<std::string,std::string>& mapRequestHeaders); -std::string HTTPError(int nStatus, bool keepalive, - bool headerOnly = false); -std::string HTTPReplyHeader(int nStatus, bool keepalive, size_t contentLength, - const char *contentType = "application/json"); -std::string HTTPReply(int nStatus, const std::string& strMsg, bool keepalive, - bool headerOnly = false, - const char *contentType = "application/json"); -bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto, - std::string& http_method, std::string& http_uri); -int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto); -int ReadHTTPHeaders(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet); -int ReadHTTPMessage(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet, - std::string& strMessageRet, int nProto, size_t max_size); -std::string JSONRPCRequest(const std::string& strMethod, const json_spirit::Array& params, const json_spirit::Value& id); -json_spirit::Object JSONRPCReplyObj(const json_spirit::Value& result, const json_spirit::Value& error, const json_spirit::Value& id); -std::string JSONRPCReply(const json_spirit::Value& result, const json_spirit::Value& error, const json_spirit::Value& id); -json_spirit::Object JSONRPCError(int code, const std::string& message); +/** Get name of RPC authentication cookie file */ +boost::filesystem::path GetAuthCookieFile(); +/** Generate a new RPC authentication cookie and write it to disk */ +bool GenerateAuthCookie(std::string *cookie_out); +/** Read the RPC authentication cookie from disk */ +bool GetAuthCookie(std::string *cookie_out); +/** Delete RPC authentication cookie from disk */ +void DeleteAuthCookie(); #endif // BITCOIN_RPCPROTOCOL_H diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 1e13f5dbba..fa3150cd7f 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -1,21 +1,28 @@ // 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. #include "base58.h" -#include "primitives/transaction.h" +#include "chain.h" +#include "coins.h" +#include "consensus/validation.h" #include "core_io.h" #include "init.h" #include "keystore.h" #include "main.h" #include "merkleblock.h" #include "net.h" +#include "policy/policy.h" +#include "primitives/transaction.h" #include "rpcserver.h" #include "script/script.h" +#include "script/script_error.h" #include "script/sign.h" #include "script/standard.h" +#include "txmempool.h" #include "uint256.h" +#include "utilstrencodings.h" #ifdef ENABLE_WALLET #include "wallet/wallet.h" #endif @@ -23,19 +30,18 @@ #include <stdint.h> #include <boost/assign/list_of.hpp> -#include "json/json_spirit_utils.h" -#include "json/json_spirit_value.h" -using namespace json_spirit; +#include "univalue/univalue.h" + using namespace std; -void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex) +void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex) { txnouttype type; vector<CTxDestination> addresses; int nRequired; - out.push_back(Pair("asm", scriptPubKey.ToString())); + out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey))); if (fIncludeHex) out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); @@ -47,27 +53,27 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeH out.push_back(Pair("reqSigs", nRequired)); out.push_back(Pair("type", GetTxnOutputType(type))); - Array a; + UniValue a(UniValue::VARR); BOOST_FOREACH(const CTxDestination& addr, addresses) a.push_back(CBitcoinAddress(addr).ToString()); out.push_back(Pair("addresses", a)); } -void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) +void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); - Array vin; + UniValue vin(UniValue::VARR); BOOST_FOREACH(const CTxIn& txin, tx.vin) { - Object in; + UniValue in(UniValue::VOBJ); if (tx.IsCoinBase()) in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); else { in.push_back(Pair("txid", txin.prevout.hash.GetHex())); in.push_back(Pair("vout", (int64_t)txin.prevout.n)); - Object o; - o.push_back(Pair("asm", txin.scriptSig.ToString())); + UniValue o(UniValue::VOBJ); + o.push_back(Pair("asm", ScriptToAsmStr(txin.scriptSig, true))); o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); } @@ -75,13 +81,13 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) vin.push_back(in); } entry.push_back(Pair("vin", vin)); - Array vout; + UniValue vout(UniValue::VARR); for (unsigned int i = 0; i < tx.vout.size(); i++) { const CTxOut& txout = tx.vout[i]; - Object out; + UniValue out(UniValue::VOBJ); out.push_back(Pair("value", ValueFromAmount(txout.nValue))); out.push_back(Pair("n", (int64_t)i)); - Object o; + UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(txout.scriptPubKey, o, true); out.push_back(Pair("scriptPubKey", o)); vout.push_back(out); @@ -104,7 +110,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) } } -Value getrawtransaction(const Array& params, bool fHelp) +UniValue getrawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -143,7 +149,7 @@ Value getrawtransaction(const Array& params, bool fHelp) " ],\n" " \"vout\" : [ (array of json objects)\n" " {\n" - " \"value\" : x.xxx, (numeric) The value in btc\n" + " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n" " \"n\" : n, (numeric) index\n" " \"scriptPubKey\" : { (json object)\n" " \"asm\" : \"asm\", (string) the asm\n" @@ -188,13 +194,13 @@ Value getrawtransaction(const Array& params, bool fHelp) if (!fVerbose) return strHex; - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("hex", strHex)); TxToJSON(tx, hashBlock, result); return result; } -Value gettxoutproof(const Array& params, bool fHelp) +UniValue gettxoutproof(const UniValue& params, bool fHelp) { if (fHelp || (params.size() != 1 && params.size() != 2)) throw runtime_error( @@ -218,8 +224,9 @@ Value gettxoutproof(const Array& params, bool fHelp) set<uint256> setTxids; uint256 oneTxid; - Array txids = params[0].get_array(); - BOOST_FOREACH(Value& txid, txids) { + UniValue txids = params[0].get_array(); + for (unsigned int idx = 0; idx < txids.size(); idx++) { + const UniValue& txid = txids[idx]; if (txid.get_str().length() != 64 || !IsHex(txid.get_str())) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str()); uint256 hash(uint256S(txid.get_str())); @@ -274,7 +281,7 @@ Value gettxoutproof(const Array& params, bool fHelp) return strHex; } -Value verifytxoutproof(const Array& params, bool fHelp) +UniValue verifytxoutproof(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -291,7 +298,7 @@ Value verifytxoutproof(const Array& params, bool fHelp) CMerkleBlock merkleBlock; ssMB >> merkleBlock; - Array res; + UniValue res(UniValue::VARR); vector<uint256> vMatch; if (merkleBlock.txn.ExtractMatches(vMatch) != merkleBlock.header.hashMerkleRoot) @@ -307,12 +314,13 @@ Value verifytxoutproof(const Array& params, bool fHelp) return res; } -Value createrawtransaction(const Array& params, bool fHelp) +UniValue createrawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 2) throw runtime_error( - "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...}\n" - "\nCreate a transaction spending the given inputs and sending to the given addresses.\n" + "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,\"data\":\"hex\",...}\n" + "\nCreate a transaction spending the given inputs and creating new outputs.\n" + "Outputs can be addresses or data.\n" "Returns hex-encoded raw transaction.\n" "Note that the transaction's inputs are not signed, and\n" "it is not stored in the wallet or transmitted to the network.\n" @@ -321,40 +329,43 @@ Value createrawtransaction(const Array& params, bool fHelp) "1. \"transactions\" (string, required) A json array of json objects\n" " [\n" " {\n" - " \"txid\":\"id\", (string, required) The transaction id\n" + " \"txid\":\"id\", (string, required) The transaction id\n" " \"vout\":n (numeric, required) The output number\n" " }\n" " ,...\n" " ]\n" - "2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n" + "2. \"outputs\" (string, required) a json object with outputs\n" " {\n" - " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the btc amount\n" - " ,...\n" + " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the " + CURRENCY_UNIT + " amount\n" + " \"data\": \"hex\", (string, required) The key is \"data\", the value is hex encoded data\n" + " ...\n" " }\n" - "\nResult:\n" "\"transaction\" (string) hex string of the transaction\n" "\nExamples\n" + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"") + + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"data\\\":\\\"00010203\\\"}\"") + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"") + + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"") ); LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(array_type)(obj_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)); - Array inputs = params[0].get_array(); - Object sendTo = params[1].get_obj(); + UniValue inputs = params[0].get_array(); + UniValue sendTo = params[1].get_obj(); CMutableTransaction rawTx; - BOOST_FOREACH(const Value& input, inputs) { - const Object& o = input.get_obj(); + for (unsigned int idx = 0; idx < inputs.size(); idx++) { + const UniValue& input = inputs[idx]; + const UniValue& o = input.get_obj(); uint256 txid = ParseHashO(o, "txid"); - const Value& vout_v = find_value(o, "vout"); - if (vout_v.type() != int_type) + const UniValue& vout_v = find_value(o, "vout"); + if (!vout_v.isNum()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key"); int nOutput = vout_v.get_int(); if (nOutput < 0) @@ -365,26 +376,35 @@ Value createrawtransaction(const Array& params, bool fHelp) } set<CBitcoinAddress> setAddress; - BOOST_FOREACH(const Pair& s, sendTo) { - CBitcoinAddress address(s.name_); - if (!address.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_); + vector<string> addrList = sendTo.getKeys(); + BOOST_FOREACH(const string& name_, addrList) { - if (setAddress.count(address)) - throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_); - setAddress.insert(address); + if (name_ == "data") { + std::vector<unsigned char> data = ParseHexV(sendTo[name_].getValStr(),"Data"); - CScript scriptPubKey = GetScriptForDestination(address.Get()); - CAmount nAmount = AmountFromValue(s.value_); + CTxOut out(0, CScript() << OP_RETURN << data); + rawTx.vout.push_back(out); + } else { + CBitcoinAddress address(name_); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_); - CTxOut out(nAmount, scriptPubKey); - rawTx.vout.push_back(out); + if (setAddress.count(address)) + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_); + setAddress.insert(address); + + CScript scriptPubKey = GetScriptForDestination(address.Get()); + CAmount nAmount = AmountFromValue(sendTo[name_]); + + CTxOut out(nAmount, scriptPubKey); + rawTx.vout.push_back(out); + } } return EncodeHexTx(rawTx); } -Value decoderawtransaction(const Array& params, bool fHelp) +UniValue decoderawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -413,7 +433,7 @@ Value decoderawtransaction(const Array& params, bool fHelp) " ],\n" " \"vout\" : [ (array of json objects)\n" " {\n" - " \"value\" : x.xxx, (numeric) The value in btc\n" + " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n" " \"n\" : n, (numeric) index\n" " \"scriptPubKey\" : { (json object)\n" " \"asm\" : \"asm\", (string) the asm\n" @@ -436,20 +456,20 @@ Value decoderawtransaction(const Array& params, bool fHelp) ); LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(str_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); CTransaction tx; if (!DecodeHexTx(tx, params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); - Object result; + UniValue result(UniValue::VOBJ); TxToJSON(tx, uint256(), result); return result; } -Value decodescript(const Array& params, bool fHelp) +UniValue decodescript(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -475,9 +495,9 @@ Value decodescript(const Array& params, bool fHelp) ); LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(str_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); - Object r; + UniValue r(UniValue::VOBJ); CScript script; if (params[0].get_str().size() > 0){ vector<unsigned char> scriptData(ParseHexV(params[0], "argument")); @@ -491,7 +511,19 @@ Value decodescript(const Array& params, bool fHelp) return r; } -Value signrawtransaction(const Array& params, bool fHelp) +/** Pushes a JSON object for script verification or signing errors to vErrorsRet. */ +static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage) +{ + UniValue entry(UniValue::VOBJ); + entry.push_back(Pair("txid", txin.prevout.hash.ToString())); + entry.push_back(Pair("vout", (uint64_t)txin.prevout.n)); + entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + entry.push_back(Pair("sequence", (uint64_t)txin.nSequence)); + entry.push_back(Pair("error", strMessage)); + vErrorsRet.push_back(entry); +} + +UniValue signrawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 4) throw runtime_error( @@ -532,8 +564,18 @@ Value signrawtransaction(const Array& params, bool fHelp) "\nResult:\n" "{\n" - " \"hex\": \"value\", (string) The raw transaction with signature(s) (hex-encoded string)\n" - " \"complete\": true|false (boolean) if transaction has a complete set of signature\n" + " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n" + " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n" + " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n" + " {\n" + " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n" + " \"vout\" : n, (numeric) The index of the output to spent and used as input\n" + " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n" + " \"sequence\" : n, (numeric) Script sequence number\n" + " \"error\" : \"text\" (string) Verification or signing error related to the input\n" + " }\n" + " ,...\n" + " ]\n" "}\n" "\nExamples:\n" @@ -546,7 +588,7 @@ Value signrawtransaction(const Array& params, bool fHelp) #else LOCK(cs_main); #endif - RPCTypeCheck(params, boost::assign::list_of(str_type)(array_type)(array_type)(str_type), true); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VARR)(UniValue::VARR)(UniValue::VSTR), true); vector<unsigned char> txData(ParseHexV(params[0], "argument 1")); CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); @@ -568,7 +610,6 @@ Value signrawtransaction(const Array& params, bool fHelp) // mergedTx will end up with all the signatures; it // starts as a clone of the rawtx: CMutableTransaction mergedTx(txVariants[0]); - bool fComplete = true; // Fetch previous transactions (inputs): CCoinsView viewDummy; @@ -590,10 +631,11 @@ Value signrawtransaction(const Array& params, bool fHelp) bool fGivenKeys = false; CBasicKeyStore tempKeystore; - if (params.size() > 2 && params[2].type() != null_type) { + if (params.size() > 2 && !params[2].isNull()) { fGivenKeys = true; - Array keys = params[2].get_array(); - BOOST_FOREACH(Value k, keys) { + UniValue keys = params[2].get_array(); + for (unsigned int idx = 0; idx < keys.size(); idx++) { + UniValue k = keys[idx]; CBitcoinSecret vchSecret; bool fGood = vchSecret.SetString(k.get_str()); if (!fGood) @@ -610,15 +652,16 @@ Value signrawtransaction(const Array& params, bool fHelp) #endif // Add previous txouts given in the RPC call: - if (params.size() > 1 && params[1].type() != null_type) { - Array prevTxs = params[1].get_array(); - BOOST_FOREACH(Value& p, prevTxs) { - if (p.type() != obj_type) + if (params.size() > 1 && !params[1].isNull()) { + UniValue prevTxs = params[1].get_array(); + for (unsigned int idx = 0; idx < prevTxs.size(); idx++) { + const UniValue& p = prevTxs[idx]; + if (!p.isObject()) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}"); - Object prevOut = p.get_obj(); + UniValue prevOut = p.get_obj(); - RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)); + RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)); uint256 txid = ParseHashO(prevOut, "txid"); @@ -633,8 +676,8 @@ Value signrawtransaction(const Array& params, bool fHelp) CCoinsModifier coins = view.ModifyCoins(txid); if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) { string err("Previous output scriptPubKey mismatch:\n"); - err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+ - scriptPubKey.ToString(); + err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + "\nvs:\n"+ + ScriptToAsmStr(scriptPubKey); throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err); } if ((unsigned int)nOut >= coins->vout.size()) @@ -646,9 +689,9 @@ Value signrawtransaction(const Array& 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()) { - RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type)); - Value v = find_value(prevOut, "redeemScript"); - if (!(v == Value::null)) { + RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)("redeemScript",UniValue::VSTR)); + UniValue v = find_value(prevOut, "redeemScript"); + if (!v.isNull()) { vector<unsigned char> rsData(ParseHexV(v, "redeemScript")); CScript redeemScript(rsData.begin(), rsData.end()); tempKeystore.AddCScript(redeemScript); @@ -664,7 +707,7 @@ Value signrawtransaction(const Array& params, bool fHelp) #endif int nHashType = SIGHASH_ALL; - if (params.size() > 3 && params[3].type() != null_type) { + if (params.size() > 3 && !params[3].isNull()) { static map<string, int> mapSigHashValues = boost::assign::map_list_of (string("ALL"), int(SIGHASH_ALL)) @@ -683,12 +726,15 @@ Value signrawtransaction(const Array& params, bool fHelp) bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); + // Script verification errors + UniValue vErrors(UniValue::VARR); + // Sign what we can: for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { CTxIn& txin = mergedTx.vin[i]; const CCoins* coins = view.AccessCoins(txin.prevout.hash); if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) { - fComplete = false; + TxInErrorToJSON(txin, vErrors, "Input not found or already spent"); continue; } const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey; @@ -702,18 +748,24 @@ Value signrawtransaction(const Array& params, bool fHelp) BOOST_FOREACH(const CMutableTransaction& 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))) - fComplete = false; + ScriptError serror = SCRIPT_ERR_OK; + if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i), &serror)) { + TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror)); + } } + bool fComplete = vErrors.empty(); - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("hex", EncodeHexTx(mergedTx))); result.push_back(Pair("complete", fComplete)); + if (!vErrors.empty()) { + result.push_back(Pair("errors", vErrors)); + } return result; } -Value sendrawtransaction(const Array& params, bool fHelp) +UniValue sendrawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -737,7 +789,7 @@ Value sendrawtransaction(const Array& params, bool fHelp) ); LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(str_type)(bool_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL)); // parse hex string from parameter CTransaction tx; @@ -756,11 +808,16 @@ Value sendrawtransaction(const Array& params, bool fHelp) if (!fHaveMempool && !fHaveChain) { // push to local node and sync with wallets CValidationState state; - if (!AcceptToMemoryPool(mempool, state, tx, false, NULL, !fOverrideFees)) { - if(state.IsInvalid()) + bool fMissingInputs; + if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) { + if (state.IsInvalid()) { throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason())); - else + } else { + if (fMissingInputs) { + throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs"); + } throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason()); + } } } else if (fHaveChain) { throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain"); diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 61dda9125b..dbee61efc8 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -12,13 +12,9 @@ #include "ui_interface.h" #include "util.h" #include "utilstrencodings.h" -#ifdef ENABLE_WALLET -#include "wallet/wallet.h" -#endif -#include <boost/algorithm/string.hpp> -#include <boost/asio.hpp> -#include <boost/asio/ssl.hpp> +#include "univalue/univalue.h" + #include <boost/bind.hpp> #include <boost/filesystem.hpp> #include <boost/foreach.hpp> @@ -27,28 +23,20 @@ #include <boost/shared_ptr.hpp> #include <boost/signals2/signal.hpp> #include <boost/thread.hpp> -#include "json/json_spirit_writer_template.h" +#include <boost/algorithm/string/case_conv.hpp> // for to_upper() -using namespace boost::asio; -using namespace json_spirit; using namespace RPCServer; using namespace std; -static std::string strRPCUserColonPass; - static bool fRPCRunning = false; static bool fRPCInWarmup = true; static std::string rpcWarmupStatus("RPC server started"); static CCriticalSection cs_rpcWarmup; - -//! These are created by StartRPCThreads, destroyed in StopRPCThreads -static boost::asio::io_service* rpc_io_service = NULL; -static map<string, boost::shared_ptr<deadline_timer> > deadlineTimers; -static ssl::context* rpc_ssl_context = NULL; -static boost::thread_group* rpc_worker_group = NULL; -static boost::asio::io_service::work *rpc_dummy_work = NULL; -static std::vector<CSubNet> rpc_allow_subnets; //!< List of subnets to allow RPC connections from -static std::vector< boost::shared_ptr<ip::tcp::acceptor> > rpc_acceptors; +/* Timer-creating functions */ +static std::vector<RPCTimerInterface*> timerInterfaces; +/* Map of name to timer. + * @note Can be changed to std::unique_ptr when C++11 */ +static std::map<std::string, boost::shared_ptr<RPCTimerBase> > deadlineTimers; static struct CRPCSignals { @@ -78,71 +66,72 @@ void RPCServer::OnPostCommand(boost::function<void (const CRPCCommand&)> slot) g_rpcSignals.PostCommand.connect(boost::bind(slot, _1)); } -void RPCTypeCheck(const Array& params, - const list<Value_type>& typesExpected, +void RPCTypeCheck(const UniValue& params, + const list<UniValue::VType>& typesExpected, bool fAllowNull) { unsigned int i = 0; - BOOST_FOREACH(Value_type t, typesExpected) + BOOST_FOREACH(UniValue::VType t, typesExpected) { if (params.size() <= i) break; - const Value& v = params[i]; - if (!((v.type() == t) || (fAllowNull && (v.type() == null_type)))) + const UniValue& v = params[i]; + if (!((v.type() == t) || (fAllowNull && (v.isNull())))) { string err = strprintf("Expected type %s, got %s", - Value_type_name[t], Value_type_name[v.type()]); + uvTypeName(t), uvTypeName(v.type())); throw JSONRPCError(RPC_TYPE_ERROR, err); } i++; } } -void RPCTypeCheck(const Object& o, - const map<string, Value_type>& typesExpected, +void RPCTypeCheckObj(const UniValue& o, + const map<string, UniValue::VType>& typesExpected, bool fAllowNull) { - BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected) + BOOST_FOREACH(const PAIRTYPE(string, UniValue::VType)& t, typesExpected) { - const Value& v = find_value(o, t.first); - if (!fAllowNull && v.type() == null_type) + 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.type() == null_type)))) + if (!((v.type() == t.second) || (fAllowNull && (v.isNull())))) { string err = strprintf("Expected type %s for %s, got %s", - Value_type_name[t.second], t.first, Value_type_name[v.type()]); + uvTypeName(t.second), t.first, uvTypeName(v.type())); throw JSONRPCError(RPC_TYPE_ERROR, err); } } } -static inline int64_t roundint64(double d) -{ - return (int64_t)(d > 0 ? d + 0.5 : d - 0.5); -} - -CAmount AmountFromValue(const Value& value) +CAmount AmountFromValue(const UniValue& value) { - double dAmount = value.get_real(); - if (dAmount <= 0.0 || dAmount > 21000000.0) - throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); - CAmount nAmount = roundint64(dAmount * COIN); - if (!MoneyRange(nAmount)) + if (!value.isNum() && !value.isStr()) + throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string"); + CAmount amount; + if (!ParseFixedPoint(value.getValStr(), 8, &amount)) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); - return nAmount; + if (!MoneyRange(amount)) + throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range"); + return amount; } -Value ValueFromAmount(const CAmount& amount) +UniValue ValueFromAmount(const CAmount& amount) { - return (double)amount / (double)COIN; + bool sign = amount < 0; + int64_t n_abs = (sign ? -amount : amount); + int64_t quotient = n_abs / COIN; + int64_t remainder = n_abs % COIN; + return UniValue(UniValue::VNUM, + strprintf("%s%d.%08d", sign ? "-" : "", quotient, remainder)); } -uint256 ParseHashV(const Value& v, string strName) +uint256 ParseHashV(const UniValue& v, string strName) { string strHex; - if (v.type() == str_type) + if (v.isStr()) strHex = v.get_str(); if (!IsHex(strHex)) // Note: IsHex("") is false throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')"); @@ -150,30 +139,29 @@ uint256 ParseHashV(const Value& v, string strName) result.SetHex(strHex); return result; } -uint256 ParseHashO(const Object& o, string strKey) +uint256 ParseHashO(const UniValue& o, string strKey) { return ParseHashV(find_value(o, strKey), strKey); } -vector<unsigned char> ParseHexV(const Value& v, string strName) +vector<unsigned char> ParseHexV(const UniValue& v, string strName) { string strHex; - if (v.type() == str_type) + if (v.isStr()) strHex = v.get_str(); if (!IsHex(strHex)) throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')"); return ParseHex(strHex); } -vector<unsigned char> ParseHexO(const Object& o, string strKey) +vector<unsigned char> ParseHexO(const UniValue& o, string strKey) { return ParseHexV(find_value(o, strKey), strKey); } - /** * Note: This interface may still be subject to change. */ -string CRPCTable::help(string strCommand) const +std::string CRPCTable::help(const std::string& strCommand) const { string strRet; string category; @@ -195,7 +183,7 @@ string CRPCTable::help(string strCommand) const continue; try { - Array params; + UniValue params; rpcfn_type pfn = pcmd->actor; if (setDone.insert(pfn).second) (*pfn)(params, true); @@ -228,7 +216,7 @@ string CRPCTable::help(string strCommand) const return strRet; } -Value help(const Array& params, bool fHelp) +UniValue help(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -248,20 +236,19 @@ Value help(const Array& params, bool fHelp) } -Value stop(const Array& params, bool fHelp) +UniValue stop(const UniValue& params, bool fHelp) { // Accept the deprecated and ignored 'detach' boolean argument if (fHelp || params.size() > 1) throw runtime_error( "stop\n" "\nStop Bitcoin server."); - // Shutdown will take long enough that the response should get back + // Event loop will exit after current HTTP requests have been handled, so + // this reply will get back to the client. StartShutdown(); return "Bitcoin server stopping"; } - - /** * Call Table */ @@ -276,11 +263,15 @@ static const CRPCCommand vRPCCommands[] = /* 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 }, @@ -288,6 +279,7 @@ static const CRPCCommand vRPCCommands[] = { "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 }, @@ -305,12 +297,10 @@ static const CRPCCommand vRPCCommands[] = { "mining", "prioritisetransaction", &prioritisetransaction, true }, { "mining", "submitblock", &submitblock, true }, -#ifdef ENABLE_WALLET /* Coin generation */ { "generating", "getgenerate", &getgenerate, true }, { "generating", "setgenerate", &setgenerate, true }, { "generating", "generate", &generate, true }, -#endif /* Raw transactions */ { "rawtransactions", "createrawtransaction", &createrawtransaction, true }, @@ -319,6 +309,9 @@ 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 }, @@ -356,6 +349,7 @@ static const CRPCCommand vRPCCommands[] = { "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 }, @@ -391,7 +385,7 @@ CRPCTable::CRPCTable() } } -const CRPCCommand *CRPCTable::operator[](string name) const +const CRPCCommand *CRPCTable::operator[](const std::string &name) const { map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name); if (it == mapCommands.end()) @@ -399,381 +393,26 @@ const CRPCCommand *CRPCTable::operator[](string name) const return (*it).second; } - -bool HTTPAuthorized(map<string, string>& mapHeaders) -{ - string strAuth = mapHeaders["authorization"]; - if (strAuth.substr(0,6) != "Basic ") - return false; - string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64); - string strUserPass = DecodeBase64(strUserPass64); - return TimingResistantEqual(strUserPass, strRPCUserColonPass); -} - -void ErrorReply(std::ostream& stream, const Object& objError, const Value& id) -{ - // Send error reply from json-rpc error object - int nStatus = HTTP_INTERNAL_SERVER_ERROR; - int code = find_value(objError, "code").get_int(); - if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST; - else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND; - string strReply = JSONRPCReply(Value::null, objError, id); - stream << HTTPReply(nStatus, strReply, false) << std::flush; -} - -CNetAddr BoostAsioToCNetAddr(boost::asio::ip::address address) +bool StartRPC() { - CNetAddr netaddr; - // Make sure that IPv4-compatible and IPv4-mapped IPv6 addresses are treated as IPv4 addresses - if (address.is_v6() - && (address.to_v6().is_v4_compatible() - || address.to_v6().is_v4_mapped())) - address = address.to_v6().to_v4(); - - if(address.is_v4()) - { - boost::asio::ip::address_v4::bytes_type bytes = address.to_v4().to_bytes(); - netaddr.SetRaw(NET_IPV4, &bytes[0]); - } - else - { - boost::asio::ip::address_v6::bytes_type bytes = address.to_v6().to_bytes(); - netaddr.SetRaw(NET_IPV6, &bytes[0]); - } - return netaddr; -} - -bool ClientAllowed(const boost::asio::ip::address& address) -{ - CNetAddr netaddr = BoostAsioToCNetAddr(address); - BOOST_FOREACH(const CSubNet &subnet, rpc_allow_subnets) - if (subnet.Match(netaddr)) - return true; - return false; -} - -template <typename Protocol> -class AcceptedConnectionImpl : public AcceptedConnection -{ -public: - AcceptedConnectionImpl( - boost::asio::io_service& io_service, - ssl::context &context, - bool fUseSSL) : - sslStream(io_service, context), - _d(sslStream, fUseSSL), - _stream(_d) - { - } - - virtual std::iostream& stream() - { - return _stream; - } - - virtual std::string peer_address_to_string() const - { - return peer.address().to_string(); - } - - virtual void close() - { - _stream.close(); - } - - typename Protocol::endpoint peer; - boost::asio::ssl::stream<typename Protocol::socket> sslStream; - -private: - SSLIOStreamDevice<Protocol> _d; - boost::iostreams::stream< SSLIOStreamDevice<Protocol> > _stream; -}; - -void ServiceConnection(AcceptedConnection *conn); - -//! Forward declaration required for RPCListen -template <typename Protocol, typename SocketAcceptorService> -static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor, - ssl::context& context, - bool fUseSSL, - boost::shared_ptr< AcceptedConnection > conn, - const boost::system::error_code& error); - -/** - * Sets up I/O resources to accept and handle a new connection. - */ -template <typename Protocol, typename SocketAcceptorService> -static void RPCListen(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor, - ssl::context& context, - const bool fUseSSL) -{ - // Accept connection - boost::shared_ptr< AcceptedConnectionImpl<Protocol> > conn(new AcceptedConnectionImpl<Protocol>(acceptor->get_io_service(), context, fUseSSL)); - - acceptor->async_accept( - conn->sslStream.lowest_layer(), - conn->peer, - boost::bind(&RPCAcceptHandler<Protocol, SocketAcceptorService>, - acceptor, - boost::ref(context), - fUseSSL, - conn, - _1)); -} - - -/** - * Accept and handle incoming connection. - */ -template <typename Protocol, typename SocketAcceptorService> -static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor, - ssl::context& context, - const bool fUseSSL, - boost::shared_ptr< AcceptedConnection > conn, - const boost::system::error_code& error) -{ - // Immediately start accepting new connections, except when we're cancelled or our socket is closed. - if (error != boost::asio::error::operation_aborted && acceptor->is_open()) - RPCListen(acceptor, context, fUseSSL); - - AcceptedConnectionImpl<ip::tcp>* tcp_conn = dynamic_cast< AcceptedConnectionImpl<ip::tcp>* >(conn.get()); - - if (error) - { - // TODO: Actually handle errors - LogPrintf("%s: Error: %s\n", __func__, error.message()); - } - // Restrict callers by IP. It is important to - // do this before starting client thread, to filter out - // certain DoS and misbehaving clients. - else if (tcp_conn && !ClientAllowed(tcp_conn->peer.address())) - { - // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake. - if (!fUseSSL) - conn->stream() << HTTPError(HTTP_FORBIDDEN, false) << std::flush; - conn->close(); - } - else { - ServiceConnection(conn.get()); - conn->close(); - } -} - -static ip::tcp::endpoint ParseEndpoint(const std::string &strEndpoint, int defaultPort) -{ - std::string addr; - int port = defaultPort; - SplitHostPort(strEndpoint, port, addr); - return ip::tcp::endpoint(boost::asio::ip::address::from_string(addr), port); -} - -void StartRPCThreads() -{ - rpc_allow_subnets.clear(); - rpc_allow_subnets.push_back(CSubNet("127.0.0.0/8")); // always allow IPv4 local subnet - rpc_allow_subnets.push_back(CSubNet("::1")); // always allow IPv6 localhost - if (mapMultiArgs.count("-rpcallowip")) - { - const vector<string>& vAllow = mapMultiArgs["-rpcallowip"]; - BOOST_FOREACH(string strAllow, vAllow) - { - CSubNet subnet(strAllow); - if(!subnet.IsValid()) - { - uiInterface.ThreadSafeMessageBox( - strprintf("Invalid -rpcallowip subnet specification: %s. Valid 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).", strAllow), - "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return; - } - rpc_allow_subnets.push_back(subnet); - } - } - std::string strAllowed; - BOOST_FOREACH(const CSubNet &subnet, rpc_allow_subnets) - strAllowed += subnet.ToString() + " "; - LogPrint("rpc", "Allowing RPC connections from: %s\n", strAllowed); - - strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; - if (((mapArgs["-rpcpassword"] == "") || - (mapArgs["-rpcuser"] == mapArgs["-rpcpassword"])) && Params().RequireRPCPassword()) - { - unsigned char rand_pwd[32]; - GetRandBytes(rand_pwd, 32); - uiInterface.ThreadSafeMessageBox(strprintf( - _("To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file:\n" - "%s\n" - "It is recommended you use the following random password:\n" - "rpcuser=bitcoinrpc\n" - "rpcpassword=%s\n" - "(you do not need to remember this password)\n" - "The username and password MUST NOT be the same.\n" - "If the file does not exist, create it with owner-readable-only file permissions.\n" - "It is also recommended to set alertnotify so you are notified of problems;\n" - "for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"), - GetConfigFile().string(), - EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32)), - "", CClientUIInterface::MSG_ERROR | CClientUIInterface::SECURE); - StartShutdown(); - return; - } - - assert(rpc_io_service == NULL); - rpc_io_service = new boost::asio::io_service(); - rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23); - - const bool fUseSSL = GetBoolArg("-rpcssl", false); - - if (fUseSSL) - { - rpc_ssl_context->set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3); - - boost::filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert")); - if (!pathCertFile.is_complete()) pathCertFile = boost::filesystem::path(GetDataDir()) / pathCertFile; - if (boost::filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string()); - else LogPrintf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string()); - - boost::filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem")); - if (!pathPKFile.is_complete()) pathPKFile = boost::filesystem::path(GetDataDir()) / pathPKFile; - if (boost::filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem); - else LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string()); - - string strCiphers = GetArg("-rpcsslciphers", "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"); - SSL_CTX_set_cipher_list(rpc_ssl_context->impl(), strCiphers.c_str()); - } - - std::vector<ip::tcp::endpoint> vEndpoints; - bool bBindAny = false; - int defaultPort = GetArg("-rpcport", BaseParams().RPCPort()); - if (!mapArgs.count("-rpcallowip")) // Default to loopback if not allowing external IPs - { - vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::loopback(), defaultPort)); - vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::loopback(), defaultPort)); - if (mapArgs.count("-rpcbind")) - { - LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n"); - } - } else if (mapArgs.count("-rpcbind")) // Specific bind address - { - BOOST_FOREACH(const std::string &addr, mapMultiArgs["-rpcbind"]) - { - try { - vEndpoints.push_back(ParseEndpoint(addr, defaultPort)); - } - catch (const boost::system::system_error&) - { - uiInterface.ThreadSafeMessageBox( - strprintf(_("Could not parse -rpcbind value %s as network address"), addr), - "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return; - } - } - } else { // No specific bind address specified, bind to any - vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::any(), defaultPort)); - vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::any(), defaultPort)); - // Prefer making the socket dual IPv6/IPv4 instead of binding - // to both addresses seperately. - bBindAny = true; - } - - bool fListening = false; - std::string strerr; - std::string straddress; - BOOST_FOREACH(const ip::tcp::endpoint &endpoint, vEndpoints) - { - try { - boost::asio::ip::address bindAddress = endpoint.address(); - straddress = bindAddress.to_string(); - LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", straddress, endpoint.port(), bBindAny); - boost::system::error_code v6_only_error; - boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service)); - - acceptor->open(endpoint.protocol()); - acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - - // Try making the socket dual IPv6/IPv4 when listening on the IPv6 "any" address - acceptor->set_option(boost::asio::ip::v6_only( - !bBindAny || bindAddress != boost::asio::ip::address_v6::any()), v6_only_error); - - acceptor->bind(endpoint); - acceptor->listen(socket_base::max_connections); - - RPCListen(acceptor, *rpc_ssl_context, fUseSSL); - - fListening = true; - rpc_acceptors.push_back(acceptor); - // If dual IPv6/IPv4 bind successful, skip binding to IPv4 separately - if(bBindAny && bindAddress == boost::asio::ip::address_v6::any() && !v6_only_error) - break; - } - catch (const boost::system::system_error& e) - { - LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", straddress, endpoint.port(), e.what()); - strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), straddress, endpoint.port(), e.what()); - } - } - - if (!fListening) { - uiInterface.ThreadSafeMessageBox(strerr, "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return; - } - - rpc_worker_group = new boost::thread_group(); - for (int i = 0; i < GetArg("-rpcthreads", 4); i++) - rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service)); + LogPrint("rpc", "Starting RPC\n"); fRPCRunning = true; g_rpcSignals.Started(); + return true; } -void StartDummyRPCThread() +void InterruptRPC() { - if(rpc_io_service == NULL) - { - rpc_io_service = new boost::asio::io_service(); - /* Create dummy "work" to keep the thread from exiting when no timeouts active, - * see http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/io_service.html#boost_asio.reference.io_service.stopping_the_io_service_from_running_out_of_work */ - rpc_dummy_work = new boost::asio::io_service::work(*rpc_io_service); - rpc_worker_group = new boost::thread_group(); - rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service)); - fRPCRunning = true; - } + LogPrint("rpc", "Interrupting RPC\n"); + // Interrupt e.g. running longpolls + fRPCRunning = false; } -void StopRPCThreads() +void StopRPC() { - if (rpc_io_service == NULL) return; - // Set this to false first, so that longpolling loops will exit when woken up - fRPCRunning = false; - - // First, cancel all timers and acceptors - // This is not done automatically by ->stop(), and in some cases the destructor of - // boost::asio::io_service can hang if this is skipped. - boost::system::error_code ec; - BOOST_FOREACH(const boost::shared_ptr<ip::tcp::acceptor> &acceptor, rpc_acceptors) - { - acceptor->cancel(ec); - if (ec) - LogPrintf("%s: Warning: %s when cancelling acceptor", __func__, ec.message()); - } - rpc_acceptors.clear(); - BOOST_FOREACH(const PAIRTYPE(std::string, boost::shared_ptr<deadline_timer>) &timer, deadlineTimers) - { - timer.second->cancel(ec); - if (ec) - LogPrintf("%s: Warning: %s when cancelling timer", __func__, ec.message()); - } + LogPrint("rpc", "Stopping RPC\n"); deadlineTimers.clear(); - - rpc_io_service->stop(); g_rpcSignals.Stopped(); - if (rpc_worker_group != NULL) - rpc_worker_group->join_all(); - delete rpc_dummy_work; rpc_dummy_work = NULL; - delete rpc_worker_group; rpc_worker_group = NULL; - delete rpc_ssl_context; rpc_ssl_context = NULL; - delete rpc_io_service; rpc_io_service = NULL; } bool IsRPCRunning() @@ -802,210 +441,78 @@ bool RPCIsInWarmup(std::string *outStatus) return fRPCInWarmup; } -void RPCRunHandler(const boost::system::error_code& err, boost::function<void(void)> func) -{ - if (!err) - func(); -} - -void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds) -{ - assert(rpc_io_service != NULL); - - if (deadlineTimers.count(name) == 0) - { - deadlineTimers.insert(make_pair(name, - boost::shared_ptr<deadline_timer>(new deadline_timer(*rpc_io_service)))); - } - deadlineTimers[name]->expires_from_now(boost::posix_time::seconds(nSeconds)); - deadlineTimers[name]->async_wait(boost::bind(RPCRunHandler, _1, func)); -} - -class JSONRequest -{ -public: - Value id; - string strMethod; - Array params; - - JSONRequest() { id = Value::null; } - void parse(const Value& valRequest); -}; - -void JSONRequest::parse(const Value& valRequest) +void JSONRequest::parse(const UniValue& valRequest) { // Parse request - if (valRequest.type() != obj_type) + if (!valRequest.isObject()) throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object"); - const Object& request = valRequest.get_obj(); + const UniValue& request = valRequest.get_obj(); // Parse id now so errors from here on will have the id id = find_value(request, "id"); // Parse method - Value valMethod = find_value(request, "method"); - if (valMethod.type() == null_type) + UniValue valMethod = find_value(request, "method"); + if (valMethod.isNull()) throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method"); - if (valMethod.type() != str_type) + if (!valMethod.isStr()) throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string"); strMethod = valMethod.get_str(); if (strMethod != "getblocktemplate") LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod)); // Parse params - Value valParams = find_value(request, "params"); - if (valParams.type() == array_type) + UniValue valParams = find_value(request, "params"); + if (valParams.isArray()) params = valParams.get_array(); - else if (valParams.type() == null_type) - params = Array(); + else if (valParams.isNull()) + params = UniValue(UniValue::VARR); else throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array"); } - -static Object JSONRPCExecOne(const Value& req) +static UniValue JSONRPCExecOne(const UniValue& req) { - Object rpc_result; + UniValue rpc_result(UniValue::VOBJ); JSONRequest jreq; try { jreq.parse(req); - Value result = tableRPC.execute(jreq.strMethod, jreq.params); - rpc_result = JSONRPCReplyObj(result, Value::null, jreq.id); + UniValue result = tableRPC.execute(jreq.strMethod, jreq.params); + rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); } - catch (const Object& objError) + catch (const UniValue& objError) { - rpc_result = JSONRPCReplyObj(Value::null, objError, jreq.id); + rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id); } catch (const std::exception& e) { - rpc_result = JSONRPCReplyObj(Value::null, + rpc_result = JSONRPCReplyObj(NullUniValue, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); } return rpc_result; } -static string JSONRPCExecBatch(const Array& vReq) +std::string JSONRPCExecBatch(const UniValue& vReq) { - Array ret; + UniValue ret(UniValue::VARR); for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) ret.push_back(JSONRPCExecOne(vReq[reqIdx])); - return write_string(Value(ret), false) + "\n"; + return ret.write() + "\n"; } -static bool HTTPReq_JSONRPC(AcceptedConnection *conn, - string& strRequest, - map<string, string>& mapHeaders, - bool fRun) +UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms) const { - // Check authorization - if (mapHeaders.count("authorization") == 0) + // Return immediately if in warmup { - conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush; - return false; + LOCK(cs_rpcWarmup); + if (fRPCInWarmup) + throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); } - if (!HTTPAuthorized(mapHeaders)) - { - LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string()); - /* Deter brute-forcing - If this results in a DoS the user really - shouldn't have their RPC port exposed. */ - MilliSleep(250); - - conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush; - return false; - } - - JSONRequest jreq; - try - { - // Parse request - Value valRequest; - if (!read_string(strRequest, valRequest)) - throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); - - // Return immediately if in warmup - { - LOCK(cs_rpcWarmup); - if (fRPCInWarmup) - throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); - } - - string strReply; - - // singleton request - if (valRequest.type() == obj_type) { - jreq.parse(valRequest); - - Value result = tableRPC.execute(jreq.strMethod, jreq.params); - - // Send reply - strReply = JSONRPCReply(result, Value::null, jreq.id); - - // array of requests - } else if (valRequest.type() == array_type) - strReply = JSONRPCExecBatch(valRequest.get_array()); - else - throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error"); - - conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, strReply.size()) << strReply << std::flush; - } - catch (const Object& objError) - { - ErrorReply(conn->stream(), objError, jreq.id); - return false; - } - catch (const std::exception& e) - { - ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); - return false; - } - return true; -} - -void ServiceConnection(AcceptedConnection *conn) -{ - bool fRun = true; - while (fRun && !ShutdownRequested()) - { - int nProto = 0; - map<string, string> mapHeaders; - string strRequest, strMethod, strURI; - - // Read HTTP request line - if (!ReadHTTPRequestLine(conn->stream(), nProto, strMethod, strURI)) - break; - - // Read HTTP message headers and body - ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto, MAX_SIZE); - - // HTTP Keep-Alive is false; close connection immediately - if ((mapHeaders["connection"] == "close") || (!GetBoolArg("-rpckeepalive", true))) - fRun = false; - - // Process via JSON-RPC API - if (strURI == "/") { - if (!HTTPReq_JSONRPC(conn, strRequest, mapHeaders, fRun)) - break; - - // Process via HTTP REST API - } else if (strURI.substr(0, 6) == "/rest/" && GetBoolArg("-rest", false)) { - if (!HTTPReq_REST(conn, strURI, mapHeaders, fRun)) - break; - - } else { - conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush; - break; - } - } -} - -json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array ¶ms) const -{ // Find method const CRPCCommand *pcmd = tableRPC[strMethod]; if (!pcmd) @@ -1026,13 +533,37 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s g_rpcSignals.PostCommand(*pcmd); } -std::string HelpExampleCli(string methodname, string args){ +std::string HelpExampleCli(const std::string& methodname, const std::string& args) +{ return "> bitcoin-cli " + methodname + " " + args + "\n"; } -std::string HelpExampleRpc(string methodname, string args){ +std::string HelpExampleRpc(const std::string& methodname, const std::string& args) +{ return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", " "\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n"; } +void RPCRegisterTimerInterface(RPCTimerInterface *iface) +{ + timerInterfaces.push_back(iface); +} + +void RPCUnregisterTimerInterface(RPCTimerInterface *iface) +{ + std::vector<RPCTimerInterface*>::iterator i = std::find(timerInterfaces.begin(), timerInterfaces.end(), iface); + assert(i != timerInterfaces.end()); + timerInterfaces.erase(i); +} + +void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds) +{ + if (timerInterfaces.empty()) + throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC"); + deadlineTimers.erase(name); + RPCTimerInterface* timerInterface = timerInterfaces[0]; + LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name()); + deadlineTimers.insert(std::make_pair(name, timerInterface->NewTimer(func, nSeconds*1000))); +} + const CRPCTable tableRPC; diff --git a/src/rpcserver.h b/src/rpcserver.h index 790104f8c9..83cc37918b 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -15,9 +15,9 @@ #include <stdint.h> #include <string> -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" +#include <boost/function.hpp> + +#include "univalue/univalue.h" class CRPCCommand; @@ -32,30 +32,21 @@ namespace RPCServer class CBlockIndex; class CNetAddr; -class AcceptedConnection +class JSONRequest { public: - virtual ~AcceptedConnection() {} + UniValue id; + std::string strMethod; + UniValue params; - virtual std::iostream& stream() = 0; - virtual std::string peer_address_to_string() const = 0; - virtual void close() = 0; + JSONRequest() { id = NullUniValue; } + void parse(const UniValue& valRequest); }; -/** Start RPC threads */ -void StartRPCThreads(); -/** - * Alternative to StartRPCThreads for the GUI, when no server is - * used. The RPC thread in this case is only used to handle timeouts. - * If real RPC threads have already been started this is a no-op. - */ -void StartDummyRPCThread(); -/** Stop RPC threads */ -void StopRPCThreads(); /** Query whether RPC is running */ bool IsRPCRunning(); -/** +/** * Set the RPC warmup status. When this is done, all RPC calls will error out * immediately with RPC_IN_WARMUP. */ @@ -71,25 +62,56 @@ bool RPCIsInWarmup(std::string *statusOut); * 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 json_spirit::Array& params, - const std::list<json_spirit::Value_type>& typesExpected, bool fAllowNull=false); +void RPCTypeCheck(const UniValue& params, + const std::list<UniValue::VType>& 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<std::string, UniValue::VType>& typesExpected, bool fAllowNull=false); + +/** Opaque base class for timers returned by NewTimerFunc. + * This provides no methods at the moment, but makes sure that delete + * cleans up the whole state. + */ +class RPCTimerBase +{ +public: + virtual ~RPCTimerBase() {} +}; + /** - * Check for expected keys/value types in an Object. - * Use like: RPCTypeCheck(object, boost::assign::map_list_of("name", str_type)("value", int_type)); + * RPC timer "driver". */ -void RPCTypeCheck(const json_spirit::Object& o, - const std::map<std::string, json_spirit::Value_type>& typesExpected, bool fAllowNull=false); +class RPCTimerInterface +{ +public: + virtual ~RPCTimerInterface() {} + /** Implementation name */ + virtual const char *Name() = 0; + /** Factory function for timers. + * RPC will call the function to create a timer that will call func in *millis* milliseconds. + * @note As the RPC mechanism is backend-neutral, it can use different implementations of timers. + * This is needed to cope with the case in which there is no HTTP server, but + * only GUI RPC console, and to break the dependency of pcserver on httprpc. + */ + virtual RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis) = 0; +}; + +/** Register factory function for timers */ +void RPCRegisterTimerInterface(RPCTimerInterface *iface); +/** Unregister factory function for timers */ +void RPCUnregisterTimerInterface(RPCTimerInterface *iface); /** - * Run func nSeconds from now. Uses boost deadline timers. + * Run func nSeconds from now. * Overrides previous timer <name> (if any). */ void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds); -//! Convert boost::asio address to CNetAddr -extern CNetAddr BoostAsioToCNetAddr(boost::asio::ip::address address); - -typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp); +typedef UniValue(*rpcfn_type)(const UniValue& params, bool fHelp); class CRPCCommand { @@ -109,17 +131,17 @@ private: std::map<std::string, const CRPCCommand*> mapCommands; public: CRPCTable(); - const CRPCCommand* operator[](std::string name) const; - std::string help(std::string name) const; + const CRPCCommand* operator[](const std::string& name) const; + std::string help(const std::string& name) const; /** * Execute a method. * @param method Method to execute - * @param params Array of arguments (JSON objects) + * @param params UniValue Array of arguments (JSON objects) * @returns Result of the call. - * @throws an exception (json_spirit::Value) when an error happens. + * @throws an exception (UniValue) when an error happens. */ - json_spirit::Value execute(const std::string &method, const json_spirit::Array ¶ms) const; + UniValue execute(const std::string &method, const UniValue ¶ms) const; }; extern const CRPCTable tableRPC; @@ -128,118 +150,121 @@ extern const CRPCTable tableRPC; * Utilities: convert hex-encoded Values * (throws error if not hex). */ -extern uint256 ParseHashV(const json_spirit::Value& v, std::string strName); -extern uint256 ParseHashO(const json_spirit::Object& o, std::string strKey); -extern std::vector<unsigned char> ParseHexV(const json_spirit::Value& v, std::string strName); -extern std::vector<unsigned char> ParseHexO(const json_spirit::Object& o, std::string strKey); - -extern void InitRPCMining(); -extern void ShutdownRPCMining(); +extern uint256 ParseHashV(const UniValue& v, std::string strName); +extern uint256 ParseHashO(const UniValue& o, std::string strKey); +extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName); +extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey); extern int64_t nWalletUnlockTime; -extern CAmount AmountFromValue(const json_spirit::Value& value); -extern json_spirit::Value ValueFromAmount(const CAmount& amount); +extern CAmount AmountFromValue(const UniValue& value); +extern UniValue ValueFromAmount(const CAmount& amount); extern double GetDifficulty(const CBlockIndex* blockindex = NULL); extern std::string HelpRequiringPassphrase(); -extern std::string HelpExampleCli(std::string methodname, std::string args); -extern std::string HelpExampleRpc(std::string methodname, std::string args); +extern std::string HelpExampleCli(const std::string& methodname, const std::string& args); +extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args); extern void EnsureWalletIsUnlocked(); -extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp -extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value ping(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value addnode(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getaddednodeinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getnettotals(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp -extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value importaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value dumpwallet(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp -extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value generate(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value estimatefee(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value estimatepriority(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp -extern json_spirit::Value getaccountaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getrawchangeaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value setaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getaddressesbyaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendtoaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value signmessage(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value verifymessage(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getreceivedbyaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getreceivedbyaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getbalance(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getunconfirmedbalance(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value movecmd(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendfrom(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendmany(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value addmultisigaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value createmultisig(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listreceivedbyaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listreceivedbyaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listtransactions(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listaddressgroupings(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listaccounts(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listsinceblock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value backupwallet(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value keypoolrefill(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value walletpassphrase(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value walletpassphrasechange(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value walletlock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value encryptwallet(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value validateaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getwalletinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblockchaininfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getnetworkinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value setmocktime(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value resendwallettransactions(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp -extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value lockunspent(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listlockunspent(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value createrawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value decoderawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value decodescript(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value signrawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendrawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettxoutproof(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value verifytxoutproof(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp -extern json_spirit::Value getbestblockhash(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getmempoolinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getchaintips(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value invalidateblock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value reconsiderblock(const json_spirit::Array& params, bool fHelp); - -// in rest.cpp -extern bool HTTPReq_REST(AcceptedConnection *conn, - const std::string& strURI, - const std::map<std::string, std::string>& mapHeaders, - bool fRun); +extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpcnet.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 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); +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 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 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); +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 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); +extern UniValue verifytxoutproof(const UniValue& params, bool fHelp); + +extern UniValue getblockcount(const UniValue& params, bool fHelp); // in rpcblockchain.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(); +std::string JSONRPCExecBatch(const UniValue& vReq); #endif // BITCOIN_RPCSERVER_H diff --git a/src/scheduler.cpp b/src/scheduler.cpp new file mode 100644 index 0000000000..184ddc28ab --- /dev/null +++ b/src/scheduler.cpp @@ -0,0 +1,131 @@ +// 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 "scheduler.h" + +#include "reverselock.h" + +#include <assert.h> +#include <boost/bind.hpp> +#include <utility> + +CScheduler::CScheduler() : nThreadsServicingQueue(0), stopRequested(false), stopWhenEmpty(false) +{ +} + +CScheduler::~CScheduler() +{ + assert(nThreadsServicingQueue == 0); +} + + +#if BOOST_VERSION < 105000 +static boost::system_time toPosixTime(const boost::chrono::system_clock::time_point& t) +{ + return boost::posix_time::from_time_t(boost::chrono::system_clock::to_time_t(t)); +} +#endif + +void CScheduler::serviceQueue() +{ + boost::unique_lock<boost::mutex> lock(newTaskMutex); + ++nThreadsServicingQueue; + + // newTaskMutex is locked throughout this loop EXCEPT + // when the thread is waiting or when the user's function + // is called. + while (!shouldStop()) { + try { + while (!shouldStop() && taskQueue.empty()) { + // Wait until there is something to do. + newTaskScheduled.wait(lock); + } + + // Wait until either there is a new task, or until + // the time of the first item on the queue: + +// wait_until needs boost 1.50 or later; older versions have timed_wait: +#if BOOST_VERSION < 105000 + while (!shouldStop() && !taskQueue.empty() && + newTaskScheduled.timed_wait(lock, toPosixTime(taskQueue.begin()->first))) { + // Keep waiting until timeout + } +#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 + } +#endif + // If there are multiple threads, the queue can empty while we're waiting (another + // thread may service the task we were waiting on). + if (shouldStop() || taskQueue.empty()) + continue; + + Function f = taskQueue.begin()->second; + taskQueue.erase(taskQueue.begin()); + + { + // Unlock before calling f, so it can reschedule itself or another task + // without deadlocking: + reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock); + f(); + } + } catch (...) { + --nThreadsServicingQueue; + throw; + } + } + --nThreadsServicingQueue; +} + +void CScheduler::stop(bool drain) +{ + { + boost::unique_lock<boost::mutex> lock(newTaskMutex); + if (drain) + stopWhenEmpty = true; + else + stopRequested = true; + } + newTaskScheduled.notify_all(); +} + +void CScheduler::schedule(CScheduler::Function f, boost::chrono::system_clock::time_point t) +{ + { + boost::unique_lock<boost::mutex> lock(newTaskMutex); + taskQueue.insert(std::make_pair(t, f)); + } + newTaskScheduled.notify_one(); +} + +void CScheduler::scheduleFromNow(CScheduler::Function f, int64_t deltaSeconds) +{ + schedule(f, boost::chrono::system_clock::now() + boost::chrono::seconds(deltaSeconds)); +} + +static void Repeat(CScheduler* s, CScheduler::Function f, int64_t deltaSeconds) +{ + f(); + s->scheduleFromNow(boost::bind(&Repeat, s, f, deltaSeconds), deltaSeconds); +} + +void CScheduler::scheduleEvery(CScheduler::Function f, int64_t deltaSeconds) +{ + scheduleFromNow(boost::bind(&Repeat, this, f, deltaSeconds), deltaSeconds); +} + +size_t CScheduler::getQueueInfo(boost::chrono::system_clock::time_point &first, + boost::chrono::system_clock::time_point &last) const +{ + boost::unique_lock<boost::mutex> lock(newTaskMutex); + size_t result = taskQueue.size(); + if (!taskQueue.empty()) { + first = taskQueue.begin()->first; + last = taskQueue.rbegin()->first; + } + return result; +} diff --git a/src/scheduler.h b/src/scheduler.h new file mode 100644 index 0000000000..436659e58b --- /dev/null +++ b/src/scheduler.h @@ -0,0 +1,83 @@ +// 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_SCHEDULER_H +#define BITCOIN_SCHEDULER_H + +// +// NOTE: +// boost::thread / boost::function / boost::chrono should be ported to +// std::thread / std::function / std::chrono when we support C++11. +// +#include <boost/function.hpp> +#include <boost/chrono/chrono.hpp> +#include <boost/thread.hpp> +#include <map> + +// +// Simple class for background tasks that should be run +// periodically or once "after a while" +// +// Usage: +// +// CScheduler* s = new CScheduler(); +// s->scheduleFromNow(doSomething, 11); // Assuming a: void doSomething() { } +// s->scheduleFromNow(boost::bind(Class::func, this, argument), 3); +// boost::thread* t = new boost::thread(boost::bind(CScheduler::serviceQueue, s)); +// +// ... then at program shutdown, clean up the thread running serviceQueue: +// t->interrupt(); +// t->join(); +// delete t; +// delete s; // Must be done after thread is interrupted/joined. +// + +class CScheduler +{ +public: + CScheduler(); + ~CScheduler(); + + typedef boost::function<void(void)> Function; + + // Call func at/after time t + void schedule(Function f, boost::chrono::system_clock::time_point t); + + // Convenience method: call f once deltaSeconds from now + void scheduleFromNow(Function f, int64_t deltaSeconds); + + // Another convenience method: call f approximately + // every deltaSeconds forever, starting deltaSeconds from now. + // To be more precise: every time f is finished, it + // is rescheduled to run deltaSeconds later. If you + // need more accurate scheduling, don't use this method. + void scheduleEvery(Function f, int64_t deltaSeconds); + + // To keep things as simple as possible, there is no unschedule. + + // Services the queue 'forever'. Should be run in a thread, + // and interrupted using boost::interrupt_thread + void serviceQueue(); + + // Tell any threads running serviceQueue to stop as soon as they're + // done servicing whatever task they're currently servicing (drain=false) + // or when there is no work left to be done (drain=true) + void stop(bool drain=false); + + // Returns number of tasks waiting to be serviced, + // and first and last task times + size_t getQueueInfo(boost::chrono::system_clock::time_point &first, + boost::chrono::system_clock::time_point &last) const; + +private: + std::multimap<boost::chrono::system_clock::time_point, Function> taskQueue; + boost::condition_variable newTaskScheduled; + mutable boost::mutex newTaskMutex; + int nThreadsServicingQueue; + bool stopRequested; + bool stopWhenEmpty; + bool shouldStop() { return stopRequested || (stopWhenEmpty && taskQueue.empty()); } +}; + +#endif diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 84a7432fdb..d3aec26020 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -188,7 +188,7 @@ bool static IsDefinedHashtypeSignature(const valtype &vchSig) { return true; } -bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) { +bool CheckSignatureEncoding(const vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror) { // Empty signature. Not strictly DER encoded, but allowed to provide a // compact way to provide an invalid signature for use with CHECK(MULTI)SIG if (vchSig.size() == 0) { @@ -335,9 +335,51 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un // Control // case OP_NOP: - break; + break; + + case OP_CHECKLOCKTIMEVERIFY: + { + if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) { + // not enabled; treat as a NOP2 + 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); + + // Note that elsewhere numeric opcodes are limited to + // operands in the range -2**31+1 to 2**31-1, however it is + // legal for opcodes to produce results exceeding that + // range. This limitation is implemented by CScriptNum's + // default 4-byte limit. + // + // If we kept to that limit we'd have a year 2038 problem, + // even though the nLockTime field in transactions + // themselves is uint32 which only becomes meaningless + // after the year 2106. + // + // Thus as a special case we tell CScriptNum to accept up + // to 5-byte bignums, which are good until 2**39-1, well + // beyond the 2**32-1 limit of the nLockTime field itself. + const CScriptNum nLockTime(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 CHECKLOCKTIMEVERIFY. + if (nLockTime < 0) + return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME); + + // Actually compare the specified lock time with the transaction. + if (!checker.CheckLockTime(nLockTime)) + return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME); + + break; + } - case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5: + case OP_NOP1: case OP_NOP3: 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) @@ -1084,6 +1126,43 @@ bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn return true; } +bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const +{ + // There are two kinds of nLockTime: lock-by-blockheight + // and lock-by-blocktime, distinguished by whether + // 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 (!( + (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 > (int64_t)txTo->nLockTime) + return false; + + // 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 + // the opcode ineffective. + // + // Testing if this vin is not final is sufficient to + // 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()) + 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); diff --git a/src/script/interpreter.h b/src/script/interpreter.h index fc64438f68..213e8c7651 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -76,8 +76,15 @@ enum // (softfork safe, BIP62 rule 6) // Note: CLEANSTACK should never be used without P2SH. SCRIPT_VERIFY_CLEANSTACK = (1U << 8), + + // Verify CHECKLOCKTIMEVERIFY + // + // See BIP65 for details. + SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), }; +bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror); + uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); class BaseSignatureChecker @@ -88,6 +95,11 @@ public: return false; } + virtual bool CheckLockTime(const CScriptNum& nLockTime) const + { + return false; + } + virtual ~BaseSignatureChecker() {} }; @@ -103,6 +115,7 @@ protected: public: TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {} bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const; + bool CheckLockTime(const CScriptNum& nLockTime) const; }; class MutableTransactionSignatureChecker : public TransactionSignatureChecker diff --git a/src/script/script.cpp b/src/script/script.cpp index fd33924732..58dbade0e2 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -8,16 +8,6 @@ #include "tinyformat.h" #include "utilstrencodings.h" -namespace { -inline std::string ValueString(const std::vector<unsigned char>& vch) -{ - if (vch.size() <= 4) - return strprintf("%d", CScriptNum(vch, false).getint()); - else - return HexStr(vch); -} -} // anon namespace - using namespace std; const char* GetOpName(opcodetype opcode) @@ -237,26 +227,3 @@ bool CScript::IsPushOnly() const } return true; } - -std::string CScript::ToString() const -{ - std::string str; - opcodetype opcode; - std::vector<unsigned char> vch; - const_iterator pc = begin(); - while (pc < end()) - { - if (!str.empty()) - str += " "; - if (!GetOp(pc, opcode, vch)) - { - str += "[error]"; - return str; - } - if (0 <= opcode && opcode <= OP_PUSHDATA4) - str += ValueString(vch); - else - str += GetOpName(opcode); - } - return str; -} diff --git a/src/script/script.h b/src/script/script.h index ed456f5c5a..f0725bbbf6 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -6,6 +6,8 @@ #ifndef BITCOIN_SCRIPT_SCRIPT_H #define BITCOIN_SCRIPT_SCRIPT_H +#include "crypto/common.h" + #include <assert.h> #include <climits> #include <limits> @@ -14,10 +16,13 @@ #include <string.h> #include <string> #include <vector> -#include "crypto/common.h" static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes +// 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 + template <typename T> std::vector<unsigned char> ToByteVector(const T& in) { @@ -150,6 +155,7 @@ enum opcodetype // expansion OP_NOP1 = 0xb0, OP_NOP2 = 0xb1, + OP_CHECKLOCKTIMEVERIFY = OP_NOP2, OP_NOP3 = 0xb2, OP_NOP4 = 0xb3, OP_NOP5 = 0xb4, @@ -195,7 +201,10 @@ public: m_value = n; } - explicit CScriptNum(const std::vector<unsigned char>& vch, bool fRequireMinimal) + static const size_t nDefaultMaxNumSize = 4; + + explicit CScriptNum(const std::vector<unsigned char>& vch, bool fRequireMinimal, + const size_t nMaxNumSize = nDefaultMaxNumSize) { if (vch.size() > nMaxNumSize) { throw scriptnum_error("script number overflow"); @@ -318,8 +327,6 @@ public: return result; } - static const size_t nMaxNumSize = 4; - private: static int64_t set_vch(const std::vector<unsigned char>& vch) { @@ -594,7 +601,6 @@ public: return (size() > 0 && *begin() == OP_RETURN); } - std::string ToString() const; void clear() { // The default std::vector::clear() does not release memory. @@ -602,4 +608,13 @@ public: } }; +class CReserveScript +{ +public: + CScript reserveScript; + virtual void KeepScript() {} + CReserveScript() {} + virtual ~CReserveScript() {} +}; + #endif // BITCOIN_SCRIPT_SCRIPT_H diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp index d8ecfde1d7..f1aa1fb408 100644 --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -47,6 +47,10 @@ const char* ScriptErrorString(const ScriptError serror) return "OP_RETURN was encountered"; case SCRIPT_ERR_UNBALANCED_CONDITIONAL: return "Invalid OP_IF construction"; + case SCRIPT_ERR_NEGATIVE_LOCKTIME: + return "Negative locktime"; + case SCRIPT_ERR_UNSATISFIED_LOCKTIME: + return "Locktime requirement not satisfied"; case SCRIPT_ERR_SIG_HASHTYPE: return "Signature hash type missing or not understood"; case SCRIPT_ERR_SIG_DER: diff --git a/src/script/script_error.h b/src/script/script_error.h index 6365680b29..bb10b8a293 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -35,6 +35,10 @@ typedef enum ScriptError_t SCRIPT_ERR_INVALID_ALTSTACK_OPERATION, SCRIPT_ERR_UNBALANCED_CONDITIONAL, + /* OP_CHECKLOCKTIMEVERIFY */ + SCRIPT_ERR_NEGATIVE_LOCKTIME, + SCRIPT_ERR_UNSATISFIED_LOCKTIME, + /* BIP62 */ SCRIPT_ERR_SIG_HASHTYPE, SCRIPT_ERR_SIG_DER, diff --git a/src/script/sign.cpp b/src/script/sign.cpp index eab629cd91..8b43183b6d 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -5,9 +5,10 @@ #include "script/sign.h" -#include "primitives/transaction.h" #include "key.h" #include "keystore.h" +#include "policy/policy.h" +#include "primitives/transaction.h" #include "script/standard.h" #include "uint256.h" @@ -275,3 +276,39 @@ CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecke return CombineSignatures(scriptPubKey, checker, txType, vSolutions, stack1, stack2); } + +namespace { +/** Dummy signature checker which accepts all signatures. */ +class DummySignatureChecker : public BaseSignatureChecker +{ +public: + DummySignatureChecker() {} + + bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const + { + return true; + } +}; +const DummySignatureChecker dummyChecker; +} + +const BaseSignatureChecker& DummySignatureCreator::Checker() const +{ + return dummyChecker; +} + +bool DummySignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode) const +{ + // Create a dummy signature that is a valid DER-encoding + vchSig.assign(72, '\000'); + vchSig[0] = 0x30; + vchSig[1] = 69; + vchSig[2] = 0x02; + vchSig[3] = 33; + vchSig[4] = 0x01; + vchSig[4 + 33] = 0x02; + vchSig[5 + 33] = 32; + vchSig[6 + 33] = 0x01; + vchSig[6 + 33 + 32] = SIGHASH_ALL; + return true; +} diff --git a/src/script/sign.h b/src/script/sign.h index 0c4cf61e5e..13f45007dd 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -43,6 +43,14 @@ public: bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode) const; }; +/** A signature creator that just produces 72-byte empty signatyres. */ +class DummySignatureCreator : public BaseSignatureCreator { +public: + DummySignatureCreator(const CKeyStore* keystoreIn) : BaseSignatureCreator(keystoreIn) {} + const BaseSignatureChecker& Checker() const; + bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode) const; +}; + /** Produce a script signature using a generic signature creator. */ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& scriptPubKey, CScript& scriptSig); diff --git a/src/script/standard.cpp b/src/script/standard.cpp index ce50e3aad8..1d5aac7b34 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -180,26 +180,6 @@ int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned c return -1; } -bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) -{ - vector<valtype> vSolutions; - if (!Solver(scriptPubKey, whichType, vSolutions)) - return false; - - if (whichType == TX_MULTISIG) - { - unsigned char m = vSolutions.front()[0]; - unsigned char n = vSolutions.back()[0]; - // Support up to x-of-3 multisig txns as standard - if (n < 1 || n > 3) - return false; - if (m < 1 || m > n) - return false; - } - - return whichType != TX_NONSTANDARD; -} - bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) { vector<valtype> vSolutions; @@ -306,6 +286,11 @@ CScript GetScriptForDestination(const CTxDestination& dest) return script; } +CScript GetScriptForRawPubKey(const CPubKey& pubKey) +{ + return CScript() << std::vector<unsigned char>(pubKey.begin(), pubKey.end()) << OP_CHECKSIG; +} + CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys) { CScript script; diff --git a/src/script/standard.h b/src/script/standard.h index a8b0acc981..9e17dac700 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -39,22 +39,6 @@ extern unsigned nMaxDatacarrierBytes; */ static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH; -/** - * Standard script verification flags that standard transactions will comply - * with. However scripts violating these flags may still be present in valid - * blocks and we must accept those blocks. - */ -static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS | - SCRIPT_VERIFY_DERSIG | - SCRIPT_VERIFY_STRICTENC | - SCRIPT_VERIFY_MINIMALDATA | - SCRIPT_VERIFY_NULLDUMMY | - SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS | - SCRIPT_VERIFY_CLEANSTACK; - -/** 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; - enum txnouttype { TX_NONSTANDARD, @@ -85,11 +69,11 @@ const char* GetTxnOutputType(txnouttype t); bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet); int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions); -bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType); bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet); bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet); CScript GetScriptForDestination(const CTxDestination& dest); +CScript GetScriptForRawPubKey(const CPubKey& pubkey); CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys); #endif // BITCOIN_SCRIPT_STANDARD_H diff --git a/src/secp256k1/.gitignore b/src/secp256k1/.gitignore index b9f7d243ec..076ff1295f 100644 --- a/src/secp256k1/.gitignore +++ b/src/secp256k1/.gitignore @@ -2,6 +2,7 @@ bench_inv bench_sign bench_verify bench_recover +bench_internal tests *.exe *.so diff --git a/src/secp256k1/.travis.yml b/src/secp256k1/.travis.yml index 40f8dae23f..0d8089cfe4 100644 --- a/src/secp256k1/.travis.yml +++ b/src/secp256k1/.travis.yml @@ -1,14 +1,14 @@ language: c +sudo: false +addons: + apt: + packages: libgmp-dev compiler: - clang - gcc -install: - - sudo apt-get install -qq libssl-dev - - if [ "$BIGNUM" = "gmp" -o "$BIGNUM" = "auto" ]; then sudo apt-get install --no-install-recommends --no-upgrade -qq libgmp-dev; fi - - if [ -n "$EXTRAPACKAGES" ]; then sudo apt-get update && sudo apt-get install --no-install-recommends --no-upgrade $EXTRAPACKAGES; fi env: global: - - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no ASM=no BUILD=check EXTRAFLAGS= HOST= EXTRAPACKAGES= + - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no ASM=no BUILD=check EXTRAFLAGS= HOST= matrix: - SCALAR=32bit - SCALAR=64bit @@ -22,8 +22,35 @@ env: - BIGNUM=no ENDOMORPHISM=yes - BUILD=distcheck - EXTRAFLAGS=CFLAGS=-DDETERMINISTIC - - HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib" - - HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib" ENDOMORPHISM=yes +matrix: + fast_finish: true + include: + - compiler: clang + env: HOST=i686-linux-gnu ENDOMORPHISM=yes + addons: + apt: + packages: + - gcc-multilib + - libgmp-dev:i386 + - compiler: clang + env: HOST=i686-linux-gnu + addons: + apt: + packages: + - gcc-multilib + - compiler: gcc + env: HOST=i686-linux-gnu ENDOMORPHISM=yes + addons: + apt: + packages: + - gcc-multilib + - compiler: gcc + env: HOST=i686-linux-gnu + addons: + apt: + packages: + - gcc-multilib + - libgmp-dev:i386 before_script: ./autogen.sh script: - if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi diff --git a/src/secp256k1/include/secp256k1.h b/src/secp256k1/include/secp256k1.h index a6e39d13db..06afd4c65b 100644 --- a/src/secp256k1/include/secp256k1.h +++ b/src/secp256k1/include/secp256k1.h @@ -40,42 +40,60 @@ extern "C" { # define SECP256K1_ARG_NONNULL(_x) # endif +/** Opaque data structure that holds context information (precomputed tables etc.). + * Only functions that take a pointer to a non-const context require exclusive + * access to it. Multiple functions that take a pointer to a const context may + * run simultaneously. + */ +typedef struct secp256k1_context_struct secp256k1_context_t; + +/** Flags to pass to secp256k1_context_create. */ +# define SECP256K1_CONTEXT_VERIFY (1 << 0) +# define SECP256K1_CONTEXT_SIGN (1 << 1) -/** Flags to pass to secp256k1_start. */ -# define SECP256K1_START_VERIFY (1 << 0) -# define SECP256K1_START_SIGN (1 << 1) +/** Create a secp256k1 context object. + * Returns: a newly created context object. + * In: flags: which parts of the context to initialize. + */ +secp256k1_context_t* secp256k1_context_create( + int flags +) SECP256K1_WARN_UNUSED_RESULT; -/** Initialize the library. This may take some time (10-100 ms). - * You need to call this before calling any other function. - * It cannot run in parallel with any other functions, but once - * secp256k1_start() returns, all other functions are thread-safe. +/** Copies a secp256k1 context object. + * Returns: a newly created context object. + * In: ctx: an existing context to copy */ -void secp256k1_start(unsigned int flags); +secp256k1_context_t* secp256k1_context_clone( + const secp256k1_context_t* ctx +) SECP256K1_WARN_UNUSED_RESULT; -/** Free all memory associated with this library. After this, no - * functions can be called anymore, except secp256k1_start() +/** Destroy a secp256k1 context object. + * The context pointer may not be used afterwards. */ -void secp256k1_stop(void); +void secp256k1_context_destroy( + secp256k1_context_t* ctx +) SECP256K1_ARG_NONNULL(1); /** Verify an ECDSA signature. * Returns: 1: correct signature * 0: incorrect signature * -1: invalid public key * -2: invalid signature - * In: msg32: the 32-byte message hash being verified (cannot be NULL) + * In: ctx: a secp256k1 context object, initialized for verification. + * msg32: the 32-byte message hash being verified (cannot be NULL) * sig: the signature being verified (cannot be NULL) * siglen: the length of the signature * pubkey: the public key to verify with (cannot be NULL) * pubkeylen: the length of pubkey - * Requires starting using SECP256K1_START_VERIFY. */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( + const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5); /** A pointer to a function to deterministically generate a nonce. * Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail. @@ -111,15 +129,14 @@ extern const secp256k1_nonce_function_t secp256k1_nonce_function_default; * Returns: 1: signature created * 0: the nonce generation function failed, the private key was invalid, or there is not * enough space in the signature (as indicated by siglen). - * In: msg32: the 32-byte message hash being signed (cannot be NULL) + * In: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * 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) * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) * In/Out: siglen: pointer to an int with the length of sig, which will be updated - * to contain the actual signature length (<=72). If 0 is returned, this will be - * set to zero. - * Requires starting using SECP256K1_START_SIGN. + * to contain the actual signature length (<=72). * * The sig always has an s value in the lower half of the range (From 0x1 * to 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, @@ -148,145 +165,180 @@ extern const secp256k1_nonce_function_t secp256k1_nonce_function_default; * be taken when this property is required for an application. */ int secp256k1_ecdsa_sign( + const secp256k1_context_t* ctx, const unsigned char *msg32, unsigned char *sig, int *siglen, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void *ndata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); /** Create a compact ECDSA signature (64 byte + recovery id). * Returns: 1: signature created * 0: the nonce generation function failed, or the secret key was invalid. - * In: msg32: the 32-byte message hash being signed (cannot be NULL) + * In: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * 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) * Out: sig: pointer to a 64-byte array where the signature will be placed (cannot be NULL) * In case 0 is returned, the returned signature length will be zero. * recid: pointer to an int, which will be updated to contain the recovery id (can be NULL) - * Requires starting using SECP256K1_START_SIGN. */ int secp256k1_ecdsa_sign_compact( + const secp256k1_context_t* ctx, const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void *ndata, int *recid -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Recover an ECDSA public key from a compact signature. * Returns: 1: public key successfully recovered (which guarantees a correct signature). * 0: otherwise. - * In: msg32: the 32-byte message hash assumed to be signed (cannot be NULL) + * In: ctx: pointer to a context object, initialized for verification (cannot be NULL) + * msg32: the 32-byte message hash assumed to be signed (cannot be NULL) * sig64: signature as 64 byte array (cannot be NULL) * compressed: whether to recover a compressed or uncompressed pubkey * recid: the recovery id (0-3, as returned by ecdsa_sign_compact) * Out: pubkey: pointer to a 33 or 65 byte array to put the pubkey (cannot be NULL) * pubkeylen: pointer to an int that will contain the pubkey length (cannot be NULL) - * Requires starting using SECP256K1_START_VERIFY. */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover_compact( + const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); /** Verify an ECDSA secret key. * Returns: 1: secret key is valid * 0: secret key is invalid - * In: seckey: pointer to a 32-byte secret key (cannot be NULL) + * In: ctx: pointer to a context object (cannot be NULL) + * seckey: pointer to a 32-byte secret key (cannot be NULL) */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(const unsigned char *seckey) SECP256K1_ARG_NONNULL(1); +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify( + const secp256k1_context_t* ctx, + const unsigned char *seckey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); /** Just validate a public key. - * Returns: 1: valid public key - * 0: invalid public key - * In: pubkey: pointer to a 33-byte or 65-byte public key (cannot be NULL). + * Returns: 1: public key is valid + * 0: public key is invalid + * In: ctx: pointer to a context object (cannot be NULL) + * pubkey: pointer to a 33-byte or 65-byte public key (cannot be NULL). * pubkeylen: length of pubkey */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_verify(const unsigned char *pubkey, int pubkeylen) SECP256K1_ARG_NONNULL(1); +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_verify( + const secp256k1_context_t* ctx, + const unsigned char *pubkey, + int pubkeylen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); /** Compute the public key for a secret key. - * In: compressed: whether the computed public key should be compressed + * In: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * compressed: whether the computed public key should be compressed * seckey: pointer to a 32-byte private key (cannot be NULL) * Out: pubkey: pointer to a 33-byte (if compressed) or 65-byte (if uncompressed) * area to store the public key (cannot be NULL) * pubkeylen: pointer to int that will be updated to contains the pubkey's * length (cannot be NULL) * Returns: 1: secret was valid, public key stores - * 0: secret was invalid, try again. - * Requires starting using SECP256K1_START_SIGN. + * 0: secret was invalid, try again */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create( + const secp256k1_context_t* ctx, unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Decompress a public key. + * In: ctx: pointer to a context object (cannot be NULL) * In/Out: pubkey: pointer to a 65-byte array to put the decompressed public key. - It must contain a 33-byte or 65-byte public key already (cannot be NULL) + * It must contain a 33-byte or 65-byte public key already (cannot be NULL) * pubkeylen: pointer to the size of the public key pointed to by pubkey (cannot be NULL) - It will be updated to reflect the new size. - * Returns: 0 if the passed public key was invalid, 1 otherwise. If 1 is returned, the - pubkey is replaced with its decompressed version. + * It will be updated to reflect the new size. + * Returns: 0: pubkey was invalid + * 1: pubkey was valid, and was replaced with its decompressed version */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_decompress( + const secp256k1_context_t* ctx, unsigned char *pubkey, int *pubkeylen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); -/** Export a private key in DER format. */ +/** Export a private key in DER format. + * In: ctx: pointer to a context object, initialized for signing (cannot be NULL) + */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_export( + const secp256k1_context_t* ctx, const unsigned char *seckey, unsigned char *privkey, int *privkeylen, int compressed -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Import a private key in DER format. */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_import( + const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *privkey, int privkeylen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Tweak a private key by adding tweak to it. */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( + const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Tweak a public key by adding tweak times the generator to it. - * Requires starting with SECP256K1_START_VERIFY. + * In: ctx: pointer to a context object, initialized for verification (cannot be NULL) */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add( + const secp256k1_context_t* ctx, unsigned char *pubkey, int pubkeylen, const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); /** Tweak a private key by multiplying it with tweak. */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul( + const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Tweak a public key by multiplying it with tweak. - * Requires starting with SECP256K1_START_VERIFY. + * In: ctx: pointer to a context object, initialized for verification (cannot be NULL) */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul( + const secp256k1_context_t* ctx, unsigned char *pubkey, int pubkeylen, const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); + +/** Updates the context randomization. + * Returns: 1: randomization successfully updated + * 0: error + * In: ctx: pointer to a context object (cannot be NULL) + * seed32: pointer to a 32-byte random seed (NULL resets to initial state) + */ +SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize( + secp256k1_context_t* ctx, + const unsigned char *seed32 +) SECP256K1_ARG_NONNULL(1); + # ifdef __cplusplus } diff --git a/src/secp256k1/src/bench.h b/src/secp256k1/src/bench.h index 0559b3e853..db5f68cee1 100644 --- a/src/secp256k1/src/bench.h +++ b/src/secp256k1/src/bench.h @@ -48,7 +48,7 @@ void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), v print_number(min * 1000000.0 / iter); printf("us / avg "); print_number((sum / count) * 1000000.0 / iter); - printf("us / avg "); + printf("us / max "); print_number(max * 1000000.0 / iter); printf("us\n"); } diff --git a/src/secp256k1/src/bench_recover.c b/src/secp256k1/src/bench_recover.c index 6991cc9d6c..56faed11a0 100644 --- a/src/secp256k1/src/bench_recover.c +++ b/src/secp256k1/src/bench_recover.c @@ -9,6 +9,7 @@ #include "bench.h" typedef struct { + secp256k1_context_t *ctx; unsigned char msg[32]; unsigned char sig[64]; } bench_recover_t; @@ -21,7 +22,7 @@ void bench_recover(void* arg) { for (i = 0; i < 20000; i++) { int j; int pubkeylen = 33; - CHECK(secp256k1_ecdsa_recover_compact(data->msg, data->sig, pubkey, &pubkeylen, 1, i % 2)); + CHECK(secp256k1_ecdsa_recover_compact(data->ctx, data->msg, data->sig, pubkey, &pubkeylen, 1, i % 2)); for (j = 0; j < 32; j++) { data->sig[j + 32] = data->msg[j]; /* Move former message to S. */ data->msg[j] = data->sig[j]; /* Move former R to message. */ @@ -40,10 +41,11 @@ void bench_recover_setup(void* arg) { int main(void) { bench_recover_t data; - secp256k1_start(SECP256K1_START_VERIFY); + + data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); run_benchmark("ecdsa_recover", bench_recover, bench_recover_setup, NULL, &data, 10, 20000); - secp256k1_stop(); + secp256k1_context_destroy(data.ctx); return 0; } diff --git a/src/secp256k1/src/bench_sign.c b/src/secp256k1/src/bench_sign.c index c5b6829a84..072a37af51 100644 --- a/src/secp256k1/src/bench_sign.c +++ b/src/secp256k1/src/bench_sign.c @@ -9,6 +9,7 @@ #include "bench.h" typedef struct { + secp256k1_context_t* ctx; unsigned char msg[32]; unsigned char key[32]; } bench_sign_t; @@ -29,7 +30,7 @@ static void bench_sign(void* arg) { for (i = 0; i < 20000; i++) { int j; int recid = 0; - CHECK(secp256k1_ecdsa_sign_compact(data->msg, sig, data->key, NULL, NULL, &recid)); + CHECK(secp256k1_ecdsa_sign_compact(data->ctx, data->msg, sig, data->key, NULL, NULL, &recid)); for (j = 0; j < 32; j++) { data->msg[j] = sig[j]; /* Move former R to message. */ data->key[j] = sig[j + 32]; /* Move former S to key. */ @@ -39,10 +40,11 @@ static void bench_sign(void* arg) { int main(void) { bench_sign_t data; - secp256k1_start(SECP256K1_START_SIGN); + + data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); run_benchmark("ecdsa_sign", bench_sign, bench_sign_setup, NULL, &data, 10, 20000); - secp256k1_stop(); + secp256k1_context_destroy(data.ctx); return 0; } diff --git a/src/secp256k1/src/bench_verify.c b/src/secp256k1/src/bench_verify.c index c279305a0d..c8c82752ce 100644 --- a/src/secp256k1/src/bench_verify.c +++ b/src/secp256k1/src/bench_verify.c @@ -12,6 +12,7 @@ #include "bench.h" typedef struct { + secp256k1_context_t *ctx; unsigned char msg[32]; unsigned char key[32]; unsigned char sig[72]; @@ -28,7 +29,7 @@ static void benchmark_verify(void* arg) { data->sig[data->siglen - 1] ^= (i & 0xFF); data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); - CHECK(secp256k1_ecdsa_verify(data->msg, data->sig, data->siglen, data->pubkey, data->pubkeylen) == (i == 0)); + CHECK(secp256k1_ecdsa_verify(data->ctx, data->msg, data->sig, data->siglen, data->pubkey, data->pubkeylen) == (i == 0)); data->sig[data->siglen - 1] ^= (i & 0xFF); data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); @@ -39,17 +40,17 @@ int main(void) { int i; benchmark_verify_t data; - secp256k1_start(SECP256K1_START_VERIFY | SECP256K1_START_SIGN); + data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); for (i = 0; i < 32; i++) data.msg[i] = 1 + i; for (i = 0; i < 32; i++) data.key[i] = 33 + i; data.siglen = 72; - secp256k1_ecdsa_sign(data.msg, data.sig, &data.siglen, data.key, NULL, NULL); + secp256k1_ecdsa_sign(data.ctx, data.msg, data.sig, &data.siglen, data.key, NULL, NULL); data.pubkeylen = 33; - CHECK(secp256k1_ec_pubkey_create(data.pubkey, &data.pubkeylen, data.key, 1)); + CHECK(secp256k1_ec_pubkey_create(data.ctx, data.pubkey, &data.pubkeylen, data.key, 1)); run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000); - secp256k1_stop(); + secp256k1_context_destroy(data.ctx); return 0; } diff --git a/src/secp256k1/src/ecdsa.h b/src/secp256k1/src/ecdsa.h index c195e7afcb..4ef78e8afb 100644 --- a/src/secp256k1/src/ecdsa.h +++ b/src/secp256k1/src/ecdsa.h @@ -9,6 +9,7 @@ #include "scalar.h" #include "group.h" +#include "ecmult.h" typedef struct { secp256k1_scalar_t r, s; @@ -16,8 +17,8 @@ typedef struct { static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size); static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a); -static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message); -static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid); -static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid); +static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message); +static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid); +static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid); #endif diff --git a/src/secp256k1/src/ecdsa_impl.h b/src/secp256k1/src/ecdsa_impl.h index 1a77649390..ed1d228189 100644 --- a/src/secp256k1/src/ecdsa_impl.h +++ b/src/secp256k1/src/ecdsa_impl.h @@ -53,35 +53,59 @@ static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned ch int lenr; int lens; int overflow; - if (sig[0] != 0x30) return 0; + if (sig[0] != 0x30) { + return 0; + } lenr = sig[3]; - if (5+lenr >= size) return 0; + if (5+lenr >= size) { + return 0; + } lens = sig[lenr+5]; - if (sig[1] != lenr+lens+4) return 0; - if (lenr+lens+6 > size) return 0; - if (sig[2] != 0x02) return 0; - if (lenr == 0) return 0; - if (sig[lenr+4] != 0x02) return 0; - if (lens == 0) return 0; + if (sig[1] != lenr+lens+4) { + return 0; + } + if (lenr+lens+6 > size) { + return 0; + } + if (sig[2] != 0x02) { + return 0; + } + if (lenr == 0) { + return 0; + } + if (sig[lenr+4] != 0x02) { + return 0; + } + if (lens == 0) { + return 0; + } sp = sig + 6 + lenr; while (lens > 0 && sp[0] == 0) { lens--; sp++; } - if (lens > 32) return 0; + if (lens > 32) { + return 0; + } rp = sig + 4; while (lenr > 0 && rp[0] == 0) { lenr--; rp++; } - if (lenr > 32) return 0; + if (lenr > 32) { + return 0; + } memcpy(ra + 32 - lenr, rp, lenr); memcpy(sa + 32 - lens, sp, lens); overflow = 0; secp256k1_scalar_set_b32(&r->r, ra, &overflow); - if (overflow) return 0; + if (overflow) { + return 0; + } secp256k1_scalar_set_b32(&r->s, sa, &overflow); - if (overflow) return 0; + if (overflow) { + return 0; + } return 1; } @@ -93,8 +117,9 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const se secp256k1_scalar_get_b32(&s[1], &a->s); while (lenR > 1 && rp[0] == 0 && rp[1] < 0x80) { lenR--; rp++; } while (lenS > 1 && sp[0] == 0 && sp[1] < 0x80) { lenS--; sp++; } - if (*size < 6+lenS+lenR) + if (*size < 6+lenS+lenR) { return 0; + } *size = 6 + lenS + lenR; sig[0] = 0x30; sig[1] = 4 + lenS + lenR; @@ -107,21 +132,22 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const se return 1; } -static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) { +static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) { unsigned char c[32]; secp256k1_scalar_t sn, u1, u2; secp256k1_fe_t xr; secp256k1_gej_t pubkeyj; secp256k1_gej_t pr; - if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) + if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) { return 0; + } secp256k1_scalar_inverse_var(&sn, &sig->s); secp256k1_scalar_mul(&u1, &sn, message); secp256k1_scalar_mul(&u2, &sn, &sig->r); secp256k1_gej_set_ge(&pubkeyj, pubkey); - secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1); + secp256k1_ecmult(ctx, &pr, &pubkeyj, &u2, &u1); if (secp256k1_gej_is_infinity(&pr)) { return 0; } @@ -160,7 +186,7 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const se return 0; } -static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) { +static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) { unsigned char brx[32]; secp256k1_fe_t fx; secp256k1_ge_t x; @@ -168,36 +194,39 @@ static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256 secp256k1_scalar_t rn, u1, u2; secp256k1_gej_t qj; - if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) + if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) { return 0; + } secp256k1_scalar_get_b32(brx, &sig->r); VERIFY_CHECK(secp256k1_fe_set_b32(&fx, brx)); /* brx comes from a scalar, so is less than the order; certainly less than p */ if (recid & 2) { - if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) + if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) { return 0; + } secp256k1_fe_add(&fx, &secp256k1_ecdsa_const_order_as_fe); } - if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) + if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) { return 0; + } secp256k1_gej_set_ge(&xj, &x); secp256k1_scalar_inverse_var(&rn, &sig->r); secp256k1_scalar_mul(&u1, &rn, message); secp256k1_scalar_negate(&u1, &u1); secp256k1_scalar_mul(&u2, &rn, &sig->s); - secp256k1_ecmult(&qj, &xj, &u2, &u1); + secp256k1_ecmult(ctx, &qj, &xj, &u2, &u1); secp256k1_ge_set_gej_var(pubkey, &qj); return !secp256k1_gej_is_infinity(&qj); } -static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid) { +static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid) { unsigned char b[32]; secp256k1_gej_t rp; secp256k1_ge_t r; secp256k1_scalar_t n; int overflow = 0; - secp256k1_ecmult_gen(&rp, nonce); + secp256k1_ecmult_gen(ctx, &rp, nonce); secp256k1_ge_set_gej(&r, &rp); secp256k1_fe_normalize(&r.x); secp256k1_fe_normalize(&r.y); @@ -209,8 +238,9 @@ static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_ secp256k1_ge_clear(&r); return 0; } - if (recid) + if (recid) { *recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0); + } secp256k1_scalar_mul(&n, &sig->r, seckey); secp256k1_scalar_add(&n, &n, message); secp256k1_scalar_inverse(&sig->s, nonce); @@ -218,12 +248,14 @@ static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_ secp256k1_scalar_clear(&n); secp256k1_gej_clear(&rp); secp256k1_ge_clear(&r); - if (secp256k1_scalar_is_zero(&sig->s)) + if (secp256k1_scalar_is_zero(&sig->s)) { return 0; + } if (secp256k1_scalar_is_high(&sig->s)) { secp256k1_scalar_negate(&sig->s, &sig->s); - if (recid) + if (recid) { *recid ^= 1; + } } return 1; } diff --git a/src/secp256k1/src/eckey.h b/src/secp256k1/src/eckey.h index 6de5dc0a59..53b818485e 100644 --- a/src/secp256k1/src/eckey.h +++ b/src/secp256k1/src/eckey.h @@ -9,16 +9,18 @@ #include "group.h" #include "scalar.h" +#include "ecmult.h" +#include "ecmult_gen.h" static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size); static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed); static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen); -static int secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed); +static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed); static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak); -static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak); +static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak); static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak); -static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak); +static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak); #endif diff --git a/src/secp256k1/src/eckey_impl.h b/src/secp256k1/src/eckey_impl.h index 3e06d05b47..a332bd34ec 100644 --- a/src/secp256k1/src/eckey_impl.h +++ b/src/secp256k1/src/eckey_impl.h @@ -24,8 +24,9 @@ static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned cha return 0; } secp256k1_ge_set_xy(elem, &x, &y); - if ((pub[0] == 0x06 || pub[0] == 0x07) && secp256k1_fe_is_odd(&y) != (pub[0] == 0x07)) + if ((pub[0] == 0x06 || pub[0] == 0x07) && secp256k1_fe_is_odd(&y) != (pub[0] == 0x07)) { return 0; + } return secp256k1_ge_is_valid_var(elem); } else { return 0; @@ -57,40 +58,47 @@ static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned int len = 0; int overflow = 0; /* sequence header */ - if (end < privkey+1 || *privkey != 0x30) + if (end < privkey+1 || *privkey != 0x30) { return 0; + } privkey++; /* sequence length constructor */ - if (end < privkey+1 || !(*privkey & 0x80)) + if (end < privkey+1 || !(*privkey & 0x80)) { return 0; + } lenb = *privkey & ~0x80; privkey++; - if (lenb < 1 || lenb > 2) + if (lenb < 1 || lenb > 2) { return 0; - if (end < privkey+lenb) + } + if (end < privkey+lenb) { return 0; + } /* sequence length */ len = privkey[lenb-1] | (lenb > 1 ? privkey[lenb-2] << 8 : 0); privkey += lenb; - if (end < privkey+len) + if (end < privkey+len) { return 0; + } /* sequence element 0: version number (=1) */ - if (end < privkey+3 || privkey[0] != 0x02 || privkey[1] != 0x01 || privkey[2] != 0x01) + if (end < privkey+3 || privkey[0] != 0x02 || privkey[1] != 0x01 || privkey[2] != 0x01) { return 0; + } privkey += 3; /* sequence element 1: octet string, up to 32 bytes */ - if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1]) + if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1]) { return 0; + } memcpy(c + 32 - privkey[1], privkey + 2, privkey[1]); secp256k1_scalar_set_b32(key, c, &overflow); memset(c, 0, 32); return !overflow; } -static int secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed) { +static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed) { secp256k1_gej_t rp; secp256k1_ge_t r; int pubkeylen = 0; - secp256k1_ecmult_gen(&rp, key); + secp256k1_ecmult_gen(ctx, &rp, key); secp256k1_ge_set_gej(&r, &rp); if (compressed) { static const unsigned char begin[] = { @@ -148,41 +156,45 @@ static int secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privke static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak) { secp256k1_scalar_add(key, key, tweak); - if (secp256k1_scalar_is_zero(key)) + if (secp256k1_scalar_is_zero(key)) { return 0; + } return 1; } -static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) { +static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) { secp256k1_gej_t pt; secp256k1_scalar_t one; secp256k1_gej_set_ge(&pt, key); secp256k1_scalar_set_int(&one, 1); - secp256k1_ecmult(&pt, &pt, &one, tweak); + secp256k1_ecmult(ctx, &pt, &pt, &one, tweak); - if (secp256k1_gej_is_infinity(&pt)) + if (secp256k1_gej_is_infinity(&pt)) { return 0; + } secp256k1_ge_set_gej(key, &pt); return 1; } static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak) { - if (secp256k1_scalar_is_zero(tweak)) + if (secp256k1_scalar_is_zero(tweak)) { return 0; + } secp256k1_scalar_mul(key, key, tweak); return 1; } -static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) { +static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) { secp256k1_scalar_t zero; secp256k1_gej_t pt; - if (secp256k1_scalar_is_zero(tweak)) + if (secp256k1_scalar_is_zero(tweak)) { return 0; + } secp256k1_scalar_set_int(&zero, 0); secp256k1_gej_set_ge(&pt, key); - secp256k1_ecmult(&pt, &pt, tweak, &zero); + secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero); secp256k1_ge_set_gej(key, &pt); return 1; } diff --git a/src/secp256k1/src/ecmult.h b/src/secp256k1/src/ecmult.h index 15a7100a4a..bab9e4ef52 100644 --- a/src/secp256k1/src/ecmult.h +++ b/src/secp256k1/src/ecmult.h @@ -10,10 +10,22 @@ #include "num.h" #include "group.h" -static void secp256k1_ecmult_start(void); -static void secp256k1_ecmult_stop(void); +typedef struct { + /* For accelerating the computation of a*P + b*G: */ + secp256k1_ge_storage_t (*pre_g)[]; /* odd multiples of the generator */ +#ifdef USE_ENDOMORPHISM + secp256k1_ge_storage_t (*pre_g_128)[]; /* odd multiples of 2^128*generator */ +#endif +} secp256k1_ecmult_context_t; + +static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx); +static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx); +static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst, + const secp256k1_ecmult_context_t *src); +static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx); +static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context_t *ctx); /** Double multiply: R = na*A + ng*G */ -static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng); +static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng); #endif diff --git a/src/secp256k1/src/ecmult_gen.h b/src/secp256k1/src/ecmult_gen.h index 42f822f9ce..3745633c47 100644 --- a/src/secp256k1/src/ecmult_gen.h +++ b/src/secp256k1/src/ecmult_gen.h @@ -10,10 +10,34 @@ #include "scalar.h" #include "group.h" -static void secp256k1_ecmult_gen_start(void); -static void secp256k1_ecmult_gen_stop(void); +typedef struct { + /* For accelerating the computation of a*G: + * To harden against timing attacks, use the following mechanism: + * * Break up the multiplicand into groups of 4 bits, called n_0, n_1, n_2, ..., n_63. + * * Compute sum(n_i * 16^i * G + U_i, i=0..63), where: + * * U_i = U * 2^i (for i=0..62) + * * U_i = U * (1-2^63) (for i=63) + * where U is a point with no known corresponding scalar. Note that sum(U_i, i=0..63) = 0. + * For each i, and each of the 16 possible values of n_i, (n_i * 16^i * G + U_i) is + * precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0..63). + * None of the resulting prec group elements have a known scalar, and neither do any of + * the intermediate sums while computing a*G. + */ + secp256k1_ge_storage_t (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */ + secp256k1_scalar_t blind; + secp256k1_gej_t initial; +} secp256k1_ecmult_gen_context_t; + +static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t* ctx); +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t* ctx); +static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *dst, + const secp256k1_ecmult_gen_context_t* src); +static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t* ctx); +static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context_t* ctx); /** Multiply with the generator: R = a*G */ -static void secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_scalar_t *a); +static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context_t* ctx, secp256k1_gej_t *r, const secp256k1_scalar_t *a); + +static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context_t *ctx, const unsigned char *seed32); #endif diff --git a/src/secp256k1/src/ecmult_gen_impl.h b/src/secp256k1/src/ecmult_gen_impl.h index 849452c7a1..4697753ac8 100644 --- a/src/secp256k1/src/ecmult_gen_impl.h +++ b/src/secp256k1/src/ecmult_gen_impl.h @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * + * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * * Distributed under the MIT software license, see the accompanying * * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ @@ -10,36 +10,23 @@ #include "scalar.h" #include "group.h" #include "ecmult_gen.h" +#include "hash_impl.h" -typedef struct { - /* For accelerating the computation of a*G: - * To harden against timing attacks, use the following mechanism: - * * Break up the multiplicand into groups of 4 bits, called n_0, n_1, n_2, ..., n_63. - * * Compute sum(n_i * 16^i * G + U_i, i=0..63), where: - * * U_i = U * 2^i (for i=0..62) - * * U_i = U * (1-2^63) (for i=63) - * where U is a point with no known corresponding scalar. Note that sum(U_i, i=0..63) = 0. - * For each i, and each of the 16 possible values of n_i, (n_i * 16^i * G + U_i) is - * precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0..63). - * None of the resulting prec group elements have a known scalar, and neither do any of - * the intermediate sums while computing a*G. - */ - secp256k1_ge_storage_t prec[64][16]; /* prec[j][i] = 16^j * i * G + U_i */ -} secp256k1_ecmult_gen_consts_t; - -static const secp256k1_ecmult_gen_consts_t *secp256k1_ecmult_gen_consts = NULL; +static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t *ctx) { + ctx->prec = NULL; +} -static void secp256k1_ecmult_gen_start(void) { +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *ctx) { secp256k1_ge_t prec[1024]; secp256k1_gej_t gj; secp256k1_gej_t nums_gej; - secp256k1_ecmult_gen_consts_t *ret; int i, j; - if (secp256k1_ecmult_gen_consts != NULL) + + if (ctx->prec != NULL) { return; + } - /* Allocate the precomputation table. */ - ret = (secp256k1_ecmult_gen_consts_t*)checked_malloc(sizeof(secp256k1_ecmult_gen_consts_t)); + ctx->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*ctx->prec)); /* get the generator */ secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); @@ -85,42 +72,113 @@ static void secp256k1_ecmult_gen_start(void) { } for (j = 0; j < 64; j++) { for (i = 0; i < 16; i++) { - secp256k1_ge_to_storage(&ret->prec[j][i], &prec[j*16 + i]); + secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*16 + i]); } } + secp256k1_ecmult_gen_blind(ctx, NULL); +} - /* Set the global pointer to the precomputation table. */ - secp256k1_ecmult_gen_consts = ret; +static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context_t* ctx) { + return ctx->prec != NULL; } -static void secp256k1_ecmult_gen_stop(void) { - secp256k1_ecmult_gen_consts_t *c; - if (secp256k1_ecmult_gen_consts == NULL) - return; +static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *dst, + const secp256k1_ecmult_gen_context_t *src) { + if (src->prec == NULL) { + dst->prec = NULL; + } else { + dst->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*dst->prec)); + memcpy(dst->prec, src->prec, sizeof(*dst->prec)); + dst->initial = src->initial; + dst->blind = src->blind; + } +} - c = (secp256k1_ecmult_gen_consts_t*)secp256k1_ecmult_gen_consts; - secp256k1_ecmult_gen_consts = NULL; - free(c); +static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t *ctx) { + free(ctx->prec); + secp256k1_scalar_clear(&ctx->blind); + secp256k1_gej_clear(&ctx->initial); + ctx->prec = NULL; } -static void secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_scalar_t *gn) { - const secp256k1_ecmult_gen_consts_t *c = secp256k1_ecmult_gen_consts; +static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_gej_t *r, const secp256k1_scalar_t *gn) { secp256k1_ge_t add; secp256k1_ge_storage_t adds; + secp256k1_scalar_t gnb; int bits; int i, j; - secp256k1_gej_set_infinity(r); + memset(&adds, 0, sizeof(adds)); + *r = ctx->initial; + /* Blind scalar/point multiplication by computing (n-b)G + bG instead of nG. */ + secp256k1_scalar_add(&gnb, gn, &ctx->blind); add.infinity = 0; for (j = 0; j < 64; j++) { - bits = secp256k1_scalar_get_bits(gn, j * 4, 4); + bits = secp256k1_scalar_get_bits(&gnb, j * 4, 4); for (i = 0; i < 16; i++) { - secp256k1_ge_storage_cmov(&adds, &c->prec[j][i], i == bits); + /** This uses a conditional move to avoid any secret data in array indexes. + * _Any_ use of secret indexes has been demonstrated to result in timing + * sidechannels, even when the cache-line access patterns are uniform. + * See also: + * "A word of warning", CHES 2013 Rump Session, by Daniel J. Bernstein and Peter Schwabe + * (https://cryptojedi.org/peter/data/chesrump-20130822.pdf) and + * "Cache Attacks and Countermeasures: the Case of AES", RSA 2006, + * by Dag Arne Osvik, Adi Shamir, and Eran Tromer + * (http://www.tau.ac.il/~tromer/papers/cache.pdf) + */ + secp256k1_ge_storage_cmov(&adds, &(*ctx->prec)[j][i], i == bits); } secp256k1_ge_from_storage(&add, &adds); secp256k1_gej_add_ge(r, r, &add); } bits = 0; secp256k1_ge_clear(&add); + secp256k1_scalar_clear(&gnb); +} + +/* Setup blinding values for secp256k1_ecmult_gen. */ +static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context_t *ctx, const unsigned char *seed32) { + secp256k1_scalar_t b; + secp256k1_gej_t gb; + secp256k1_fe_t s; + unsigned char nonce32[32]; + secp256k1_rfc6979_hmac_sha256_t rng; + int retry; + if (!seed32) { + /* When seed is NULL, reset the initial point and blinding value. */ + secp256k1_gej_set_ge(&ctx->initial, &secp256k1_ge_const_g); + secp256k1_gej_neg(&ctx->initial, &ctx->initial); + secp256k1_scalar_set_int(&ctx->blind, 1); + } + /* The prior blinding value (if not reset) is chained forward by including it in the hash. */ + secp256k1_scalar_get_b32(nonce32, &ctx->blind); + /** Using a CSPRNG allows a failure free interface, avoids needing large amounts of random data, + * and guards against weak or adversarial seeds. This is a simpler and safer interface than + * asking the caller for blinding values directly and expecting them to retry on failure. + */ + secp256k1_rfc6979_hmac_sha256_initialize(&rng, seed32 ? seed32 : nonce32, 32, nonce32, 32, NULL, 0); + /* Retry for out of range results to achieve uniformity. */ + do { + secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); + retry = !secp256k1_fe_set_b32(&s, nonce32); + retry |= secp256k1_fe_is_zero(&s); + } while (retry); + /* Randomize the projection to defend against multiplier sidechannels. */ + secp256k1_gej_rescale(&ctx->initial, &s); + secp256k1_fe_clear(&s); + do { + secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); + secp256k1_scalar_set_b32(&b, nonce32, &retry); + /* A blinding value of 0 works, but would undermine the projection hardening. */ + retry |= secp256k1_scalar_is_zero(&b); + } while (retry); + secp256k1_rfc6979_hmac_sha256_finalize(&rng); + memset(nonce32, 0, 32); + secp256k1_ecmult_gen(ctx, &gb, &b); + secp256k1_scalar_negate(&b, &b); + ctx->blind = b; + ctx->initial = gb; + secp256k1_scalar_clear(&b); + secp256k1_gej_clear(&gb); } #endif diff --git a/src/secp256k1/src/ecmult_impl.h b/src/secp256k1/src/ecmult_impl.h index ece0b0a459..1b2856f83d 100644 --- a/src/secp256k1/src/ecmult_impl.h +++ b/src/secp256k1/src/ecmult_impl.h @@ -41,16 +41,17 @@ static void secp256k1_ecmult_table_precomp_gej_var(secp256k1_gej_t *pre, const s int i; pre[0] = *a; secp256k1_gej_double_var(&d, &pre[0]); - for (i = 1; i < (1 << (w-2)); i++) + for (i = 1; i < (1 << (w-2)); i++) { secp256k1_gej_add_var(&pre[i], &d, &pre[i-1]); + } } static void secp256k1_ecmult_table_precomp_ge_storage_var(secp256k1_ge_storage_t *pre, const secp256k1_gej_t *a, int w) { secp256k1_gej_t d; int i; const int table_size = 1 << (w-2); - secp256k1_gej_t *prej = checked_malloc(sizeof(secp256k1_gej_t) * table_size); - secp256k1_ge_t *prea = checked_malloc(sizeof(secp256k1_ge_t) * table_size); + secp256k1_gej_t *prej = (secp256k1_gej_t *)checked_malloc(sizeof(secp256k1_gej_t) * table_size); + secp256k1_ge_t *prea = (secp256k1_ge_t *)checked_malloc(sizeof(secp256k1_ge_t) * table_size); prej[0] = *a; secp256k1_gej_double_var(&d, a); for (i = 1; i < table_size; i++) { @@ -73,73 +74,93 @@ static void secp256k1_ecmult_table_precomp_ge_storage_var(secp256k1_ge_storage_t VERIFY_CHECK(((n) & 1) == 1); \ VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ - if ((n) > 0) \ + if ((n) > 0) { \ *(r) = (pre)[((n)-1)/2]; \ - else \ + } else { \ secp256k1_gej_neg((r), &(pre)[(-(n)-1)/2]); \ + } \ } while(0) #define ECMULT_TABLE_GET_GE_STORAGE(r,pre,n,w) do { \ VERIFY_CHECK(((n) & 1) == 1); \ VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ - if ((n) > 0) \ + if ((n) > 0) { \ secp256k1_ge_from_storage((r), &(pre)[((n)-1)/2]); \ - else {\ + } else { \ secp256k1_ge_from_storage((r), &(pre)[(-(n)-1)/2]); \ secp256k1_ge_neg((r), (r)); \ } \ } while(0) -typedef struct { - /* For accelerating the computation of a*P + b*G: */ - secp256k1_ge_storage_t pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of the generator */ +static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx) { + ctx->pre_g = NULL; #ifdef USE_ENDOMORPHISM - secp256k1_ge_storage_t pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of 2^128*generator */ + ctx->pre_g_128 = NULL; #endif -} secp256k1_ecmult_consts_t; - -static const secp256k1_ecmult_consts_t *secp256k1_ecmult_consts = NULL; +} -static void secp256k1_ecmult_start(void) { +static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx) { secp256k1_gej_t gj; - secp256k1_ecmult_consts_t *ret; - if (secp256k1_ecmult_consts != NULL) - return; - /* Allocate the precomputation table. */ - ret = (secp256k1_ecmult_consts_t*)checked_malloc(sizeof(secp256k1_ecmult_consts_t)); + if (ctx->pre_g != NULL) { + return; + } /* get the generator */ secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); + ctx->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); /* precompute the tables with odd multiples */ - secp256k1_ecmult_table_precomp_ge_storage_var(ret->pre_g, &gj, WINDOW_G); + secp256k1_ecmult_table_precomp_ge_storage_var(*ctx->pre_g, &gj, WINDOW_G); #ifdef USE_ENDOMORPHISM { secp256k1_gej_t g_128j; int i; + + ctx->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); + /* calculate 2^128*generator */ g_128j = gj; - for (i = 0; i < 128; i++) + for (i = 0; i < 128; i++) { secp256k1_gej_double_var(&g_128j, &g_128j); - secp256k1_ecmult_table_precomp_ge_storage_var(ret->pre_g_128, &g_128j, WINDOW_G); + } + secp256k1_ecmult_table_precomp_ge_storage_var(*ctx->pre_g_128, &g_128j, WINDOW_G); } #endif +} - /* Set the global pointer to the precomputation table. */ - secp256k1_ecmult_consts = ret; +static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst, + const secp256k1_ecmult_context_t *src) { + if (src->pre_g == NULL) { + dst->pre_g = NULL; + } else { + size_t size = sizeof((*dst->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G); + dst->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(size); + memcpy(dst->pre_g, src->pre_g, size); + } +#ifdef USE_ENDOMORPHISM + if (src->pre_g_128 == NULL) { + dst->pre_g_128 = NULL; + } else { + size_t size = sizeof((*dst->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G); + dst->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(size); + memcpy(dst->pre_g_128, src->pre_g_128, size); + } +#endif } -static void secp256k1_ecmult_stop(void) { - secp256k1_ecmult_consts_t *c; - if (secp256k1_ecmult_consts == NULL) - return; +static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context_t *ctx) { + return ctx->pre_g != NULL; +} - c = (secp256k1_ecmult_consts_t*)secp256k1_ecmult_consts; - secp256k1_ecmult_consts = NULL; - free(c); +static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx) { + free(ctx->pre_g); +#ifdef USE_ENDOMORPHISM + free(ctx->pre_g_128); +#endif + secp256k1_ecmult_context_init(ctx); } /** Convert a number to WNAF notation. The number becomes represented by sum(2^i * wnaf[i], i=0..bits), @@ -186,11 +207,10 @@ static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_scalar_t *a, int w) return set_bits; } -static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng) { +static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng) { secp256k1_gej_t tmpj; secp256k1_gej_t pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; secp256k1_ge_t tmpa; - const secp256k1_ecmult_consts_t *c = secp256k1_ecmult_consts; #ifdef USE_ENDOMORPHISM secp256k1_gej_t pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; secp256k1_scalar_t na_1, na_lam; @@ -223,7 +243,9 @@ static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const VERIFY_CHECK(bits_na_1 <= 130); VERIFY_CHECK(bits_na_lam <= 130); bits = bits_na_1; - if (bits_na_lam > bits) bits = bits_na_lam; + if (bits_na_lam > bits) { + bits = bits_na_lam; + } #else /* build wnaf representation for na. */ bits_na = secp256k1_ecmult_wnaf(wnaf_na, na, WINDOW_A); @@ -234,8 +256,9 @@ static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ecmult_table_precomp_gej_var(pre_a, a, WINDOW_A); #ifdef USE_ENDOMORPHISM - for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) + for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { secp256k1_gej_mul_lambda(&pre_a_lam[i], &pre_a[i]); + } /* split ng into ng_1 and ng_128 (where gn = gn_1 + gn_128*2^128, and gn_1 and gn_128 are ~128 bit) */ secp256k1_scalar_split_128(&ng_1, &ng_128, ng); @@ -243,11 +266,17 @@ static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const /* Build wnaf representation for ng_1 and ng_128 */ bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, &ng_1, WINDOW_G); bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, &ng_128, WINDOW_G); - if (bits_ng_1 > bits) bits = bits_ng_1; - if (bits_ng_128 > bits) bits = bits_ng_128; + if (bits_ng_1 > bits) { + bits = bits_ng_1; + } + if (bits_ng_128 > bits) { + bits = bits_ng_128; + } #else bits_ng = secp256k1_ecmult_wnaf(wnaf_ng, ng, WINDOW_G); - if (bits_ng > bits) bits = bits_ng; + if (bits_ng > bits) { + bits = bits_ng; + } #endif secp256k1_gej_set_infinity(r); @@ -265,11 +294,11 @@ static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_add_var(r, r, &tmpj); } if (i < bits_ng_1 && (n = wnaf_ng_1[i])) { - ECMULT_TABLE_GET_GE_STORAGE(&tmpa, c->pre_g, n, WINDOW_G); + ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G); secp256k1_gej_add_ge_var(r, r, &tmpa); } if (i < bits_ng_128 && (n = wnaf_ng_128[i])) { - ECMULT_TABLE_GET_GE_STORAGE(&tmpa, c->pre_g_128, n, WINDOW_G); + ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g_128, n, WINDOW_G); secp256k1_gej_add_ge_var(r, r, &tmpa); } #else @@ -278,7 +307,7 @@ static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_add_var(r, r, &tmpj); } if (i < bits_ng && (n = wnaf_ng[i])) { - ECMULT_TABLE_GET_GE_STORAGE(&tmpa, c->pre_g, n, WINDOW_G); + ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G); secp256k1_gej_add_ge_var(r, r, &tmpa); } #endif diff --git a/src/secp256k1/src/field.h b/src/secp256k1/src/field.h index 9e6d7d3c04..41b280892d 100644 --- a/src/secp256k1/src/field.h +++ b/src/secp256k1/src/field.h @@ -113,4 +113,7 @@ static void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_stor /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ static void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag); +/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ +static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag); + #endif diff --git a/src/secp256k1/src/field_10x26_impl.h b/src/secp256k1/src/field_10x26_impl.h index 0afbb18a4a..871b91f912 100644 --- a/src/secp256k1/src/field_10x26_impl.h +++ b/src/secp256k1/src/field_10x26_impl.h @@ -236,8 +236,9 @@ static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { z1 = z0 ^ 0x3D0UL; /* Fast return path should catch the majority of cases */ - if ((z0 != 0UL) & (z1 != 0x3FFFFFFUL)) + if ((z0 != 0UL) & (z1 != 0x3FFFFFFUL)) { return 0; + } t1 = r->n[1]; t2 = r->n[2]; @@ -315,8 +316,12 @@ static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b secp256k1_fe_verify(b); #endif for (i = 9; i >= 0; i--) { - if (a->n[i] > b->n[i]) return 1; - if (a->n[i] < b->n[i]) return -1; + if (a->n[i] > b->n[i]) { + return 1; + } + if (a->n[i] < b->n[i]) { + return -1; + } } return 0; } @@ -1063,6 +1068,26 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { #endif } +static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) { + uint32_t mask0, mask1; + mask0 = flag + ~((uint32_t)0); + mask1 = ~mask0; + r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); + r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); + r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); + r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); + r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); + r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1); + r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1); + r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); + r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1); + r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1); +#ifdef VERIFY + r->magnitude = (r->magnitude & mask0) | (a->magnitude & mask1); + r->normalized = (r->normalized & mask0) | (a->normalized & mask1); +#endif +} + static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag) { uint32_t mask0, mask1; mask0 = flag + ~((uint32_t)0); diff --git a/src/secp256k1/src/field_5x52_impl.h b/src/secp256k1/src/field_5x52_impl.h index 2f9c8704a8..bda4c3dfc2 100644 --- a/src/secp256k1/src/field_5x52_impl.h +++ b/src/secp256k1/src/field_5x52_impl.h @@ -209,8 +209,9 @@ static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { z1 = z0 ^ 0x1000003D0ULL; /* Fast return path should catch the majority of cases */ - if ((z0 != 0ULL) & (z1 != 0xFFFFFFFFFFFFFULL)) + if ((z0 != 0ULL) & (z1 != 0xFFFFFFFFFFFFFULL)) { return 0; + } t1 = r->n[1]; t2 = r->n[2]; @@ -277,8 +278,12 @@ static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b secp256k1_fe_verify(b); #endif for (i = 4; i >= 0; i--) { - if (a->n[i] > b->n[i]) return 1; - if (a->n[i] < b->n[i]) return -1; + if (a->n[i] > b->n[i]) { + return 1; + } + if (a->n[i] < b->n[i]) { + return -1; + } } return 0; } @@ -399,6 +404,21 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { #endif } +static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) { + uint64_t mask0, mask1; + mask0 = flag + ~((uint64_t)0); + mask1 = ~mask0; + r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); + r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); + r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); + r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); + r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); +#ifdef VERIFY + r->magnitude = (r->magnitude & mask0) | (a->magnitude & mask1); + r->normalized = (r->normalized & mask0) | (a->normalized & mask1); +#endif +} + static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag) { uint64_t mask0, mask1; mask0 = flag + ~((uint64_t)0); diff --git a/src/secp256k1/src/field_impl.h b/src/secp256k1/src/field_impl.h index 047914cf28..e6ec11e8f2 100644 --- a/src/secp256k1/src/field_impl.h +++ b/src/secp256k1/src/field_impl.h @@ -44,47 +44,69 @@ static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { secp256k1_fe_mul(&x3, &x3, a); x6 = x3; - for (j=0; j<3; j++) secp256k1_fe_sqr(&x6, &x6); + for (j=0; j<3; j++) { + secp256k1_fe_sqr(&x6, &x6); + } secp256k1_fe_mul(&x6, &x6, &x3); x9 = x6; - for (j=0; j<3; j++) secp256k1_fe_sqr(&x9, &x9); + for (j=0; j<3; j++) { + secp256k1_fe_sqr(&x9, &x9); + } secp256k1_fe_mul(&x9, &x9, &x3); x11 = x9; - for (j=0; j<2; j++) secp256k1_fe_sqr(&x11, &x11); + for (j=0; j<2; j++) { + secp256k1_fe_sqr(&x11, &x11); + } secp256k1_fe_mul(&x11, &x11, &x2); x22 = x11; - for (j=0; j<11; j++) secp256k1_fe_sqr(&x22, &x22); + for (j=0; j<11; j++) { + secp256k1_fe_sqr(&x22, &x22); + } secp256k1_fe_mul(&x22, &x22, &x11); x44 = x22; - for (j=0; j<22; j++) secp256k1_fe_sqr(&x44, &x44); + for (j=0; j<22; j++) { + secp256k1_fe_sqr(&x44, &x44); + } secp256k1_fe_mul(&x44, &x44, &x22); x88 = x44; - for (j=0; j<44; j++) secp256k1_fe_sqr(&x88, &x88); + for (j=0; j<44; j++) { + secp256k1_fe_sqr(&x88, &x88); + } secp256k1_fe_mul(&x88, &x88, &x44); x176 = x88; - for (j=0; j<88; j++) secp256k1_fe_sqr(&x176, &x176); + for (j=0; j<88; j++) { + secp256k1_fe_sqr(&x176, &x176); + } secp256k1_fe_mul(&x176, &x176, &x88); x220 = x176; - for (j=0; j<44; j++) secp256k1_fe_sqr(&x220, &x220); + for (j=0; j<44; j++) { + secp256k1_fe_sqr(&x220, &x220); + } secp256k1_fe_mul(&x220, &x220, &x44); x223 = x220; - for (j=0; j<3; j++) secp256k1_fe_sqr(&x223, &x223); + for (j=0; j<3; j++) { + secp256k1_fe_sqr(&x223, &x223); + } secp256k1_fe_mul(&x223, &x223, &x3); /* The final result is then assembled using a sliding window over the blocks. */ t1 = x223; - for (j=0; j<23; j++) secp256k1_fe_sqr(&t1, &t1); + for (j=0; j<23; j++) { + secp256k1_fe_sqr(&t1, &t1); + } secp256k1_fe_mul(&t1, &t1, &x22); - for (j=0; j<6; j++) secp256k1_fe_sqr(&t1, &t1); + for (j=0; j<6; j++) { + secp256k1_fe_sqr(&t1, &t1); + } secp256k1_fe_mul(&t1, &t1, &x2); secp256k1_fe_sqr(&t1, &t1); secp256k1_fe_sqr(r, &t1); @@ -111,51 +133,77 @@ static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a) { secp256k1_fe_mul(&x3, &x3, a); x6 = x3; - for (j=0; j<3; j++) secp256k1_fe_sqr(&x6, &x6); + for (j=0; j<3; j++) { + secp256k1_fe_sqr(&x6, &x6); + } secp256k1_fe_mul(&x6, &x6, &x3); x9 = x6; - for (j=0; j<3; j++) secp256k1_fe_sqr(&x9, &x9); + for (j=0; j<3; j++) { + secp256k1_fe_sqr(&x9, &x9); + } secp256k1_fe_mul(&x9, &x9, &x3); x11 = x9; - for (j=0; j<2; j++) secp256k1_fe_sqr(&x11, &x11); + for (j=0; j<2; j++) { + secp256k1_fe_sqr(&x11, &x11); + } secp256k1_fe_mul(&x11, &x11, &x2); x22 = x11; - for (j=0; j<11; j++) secp256k1_fe_sqr(&x22, &x22); + for (j=0; j<11; j++) { + secp256k1_fe_sqr(&x22, &x22); + } secp256k1_fe_mul(&x22, &x22, &x11); x44 = x22; - for (j=0; j<22; j++) secp256k1_fe_sqr(&x44, &x44); + for (j=0; j<22; j++) { + secp256k1_fe_sqr(&x44, &x44); + } secp256k1_fe_mul(&x44, &x44, &x22); x88 = x44; - for (j=0; j<44; j++) secp256k1_fe_sqr(&x88, &x88); + for (j=0; j<44; j++) { + secp256k1_fe_sqr(&x88, &x88); + } secp256k1_fe_mul(&x88, &x88, &x44); x176 = x88; - for (j=0; j<88; j++) secp256k1_fe_sqr(&x176, &x176); + for (j=0; j<88; j++) { + secp256k1_fe_sqr(&x176, &x176); + } secp256k1_fe_mul(&x176, &x176, &x88); x220 = x176; - for (j=0; j<44; j++) secp256k1_fe_sqr(&x220, &x220); + for (j=0; j<44; j++) { + secp256k1_fe_sqr(&x220, &x220); + } secp256k1_fe_mul(&x220, &x220, &x44); x223 = x220; - for (j=0; j<3; j++) secp256k1_fe_sqr(&x223, &x223); + for (j=0; j<3; j++) { + secp256k1_fe_sqr(&x223, &x223); + } secp256k1_fe_mul(&x223, &x223, &x3); /* The final result is then assembled using a sliding window over the blocks. */ t1 = x223; - for (j=0; j<23; j++) secp256k1_fe_sqr(&t1, &t1); + for (j=0; j<23; j++) { + secp256k1_fe_sqr(&t1, &t1); + } secp256k1_fe_mul(&t1, &t1, &x22); - for (j=0; j<5; j++) secp256k1_fe_sqr(&t1, &t1); + for (j=0; j<5; j++) { + secp256k1_fe_sqr(&t1, &t1); + } secp256k1_fe_mul(&t1, &t1, a); - for (j=0; j<3; j++) secp256k1_fe_sqr(&t1, &t1); + for (j=0; j<3; j++) { + secp256k1_fe_sqr(&t1, &t1); + } secp256k1_fe_mul(&t1, &t1, &x2); - for (j=0; j<2; j++) secp256k1_fe_sqr(&t1, &t1); + for (j=0; j<2; j++) { + secp256k1_fe_sqr(&t1, &t1); + } secp256k1_fe_mul(r, a, &t1); } @@ -188,8 +236,9 @@ static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp256k1_fe_t *a) { secp256k1_fe_t u; size_t i; - if (len < 1) + if (len < 1) { return; + } VERIFY_CHECK((r + len <= a) || (a + len <= r)); diff --git a/src/secp256k1/src/group.h b/src/secp256k1/src/group.h index d1e5834909..0b08b3b991 100644 --- a/src/secp256k1/src/group.h +++ b/src/secp256k1/src/group.h @@ -115,4 +115,7 @@ static void secp256k1_ge_from_storage(secp256k1_ge_t *r, const secp256k1_ge_stor /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ static void secp256k1_ge_storage_cmov(secp256k1_ge_storage_t *r, const secp256k1_ge_storage_t *a, int flag); +/** Rescale a jacobian point by b which must be non-zero. Constant-time. */ +static void secp256k1_gej_rescale(secp256k1_gej_t *r, const secp256k1_fe_t *b); + #endif diff --git a/src/secp256k1/src/group_impl.h b/src/secp256k1/src/group_impl.h index 8d8c359c5a..0f64576fbb 100644 --- a/src/secp256k1/src/group_impl.h +++ b/src/secp256k1/src/group_impl.h @@ -77,14 +77,14 @@ static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const se secp256k1_fe_t *azi; size_t i; size_t count = 0; - az = checked_malloc(sizeof(secp256k1_fe_t) * len); + az = (secp256k1_fe_t *)checked_malloc(sizeof(secp256k1_fe_t) * len); for (i = 0; i < len; i++) { if (!a[i].infinity) { az[count++] = a[i].z; } } - azi = checked_malloc(sizeof(secp256k1_fe_t) * count); + azi = (secp256k1_fe_t *)checked_malloc(sizeof(secp256k1_fe_t) * count); secp256k1_fe_inv_all_var(count, azi, az); free(az); @@ -138,11 +138,13 @@ static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, i r->infinity = 0; secp256k1_fe_set_int(&c, 7); secp256k1_fe_add(&c, &x3); - if (!secp256k1_fe_sqrt_var(&r->y, &c)) + if (!secp256k1_fe_sqrt_var(&r->y, &c)) { return 0; + } secp256k1_fe_normalize_var(&r->y); - if (secp256k1_fe_is_odd(&r->y) != odd) + if (secp256k1_fe_is_odd(&r->y) != odd) { secp256k1_fe_negate(&r->y, &r->y, 1); + } return 1; } @@ -176,8 +178,9 @@ static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a) { static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) { secp256k1_fe_t y2, x3, z2, z6; - if (a->infinity) + if (a->infinity) { return 0; + } /** y^2 = x^3 + 7 * (Y/Z^3)^2 = (X/Z^2)^3 + 7 * Y^2 / Z^6 = X^3 / Z^6 + 7 @@ -195,8 +198,9 @@ static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) { static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) { secp256k1_fe_t y2, x3, c; - if (a->infinity) + if (a->infinity) { return 0; + } /* y^2 = x^3 + 7 */ secp256k1_fe_sqr(&y2, &a->y); secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); @@ -321,7 +325,8 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t * } static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b) { - /* Operations: 7 mul, 5 sqr, 5 normalize, 19 mul_int/add/negate */ + /* Operations: 7 mul, 5 sqr, 5 normalize, 17 mul_int/add/negate/cmov */ + static const secp256k1_fe_t fe_1 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); secp256k1_fe_t zz, u1, u2, s1, s2, z, t, m, n, q, rr; int infinity; VERIFY_CHECK(!b->infinity); @@ -383,17 +388,25 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c secp256k1_fe_mul_int(&r->y, 4 * (1 - a->infinity)); /* r->y = Y3 = 4*R*(3*Q-2*R^2)-4*M^4 (4) */ /** In case a->infinity == 1, the above code results in r->x, r->y, and r->z all equal to 0. - * Add b->x to x, b->y to y, and 1 to z in that case. + * Replace r with b->x, b->y, 1 in that case. */ - t = b->x; secp256k1_fe_mul_int(&t, a->infinity); - secp256k1_fe_add(&r->x, &t); - t = b->y; secp256k1_fe_mul_int(&t, a->infinity); - secp256k1_fe_add(&r->y, &t); - secp256k1_fe_set_int(&t, a->infinity); - secp256k1_fe_add(&r->z, &t); + secp256k1_fe_cmov(&r->x, &b->x, a->infinity); + secp256k1_fe_cmov(&r->y, &b->y, a->infinity); + secp256k1_fe_cmov(&r->z, &fe_1, a->infinity); r->infinity = infinity; } +static void secp256k1_gej_rescale(secp256k1_gej_t *r, const secp256k1_fe_t *s) { + /* Operations: 4 mul, 1 sqr */ + secp256k1_fe_t zz; + VERIFY_CHECK(!secp256k1_fe_is_zero(s)); + secp256k1_fe_sqr(&zz, s); + secp256k1_fe_mul(&r->x, &r->x, &zz); /* r->x *= s^2 */ + secp256k1_fe_mul(&r->y, &r->y, &zz); + secp256k1_fe_mul(&r->y, &r->y, s); /* r->y *= s^3 */ + secp256k1_fe_mul(&r->z, &r->z, s); /* r->z *= s */ +} + static void secp256k1_ge_to_storage(secp256k1_ge_storage_t *r, const secp256k1_ge_t *a) { secp256k1_fe_t x, y; VERIFY_CHECK(!a->infinity); diff --git a/src/secp256k1/src/hash_impl.h b/src/secp256k1/src/hash_impl.h index 60fdbf7718..9828827bcd 100644 --- a/src/secp256k1/src/hash_impl.h +++ b/src/secp256k1/src/hash_impl.h @@ -176,13 +176,15 @@ static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, cons } secp256k1_sha256_initialize(&hash->outer); - for (n = 0; n < 64; n++) + for (n = 0; n < 64; n++) { rkey[n] ^= 0x5c; + } secp256k1_sha256_write(&hash->outer, rkey, 64); secp256k1_sha256_initialize(&hash->inner); - for (n = 0; n < 64; n++) + for (n = 0; n < 64; n++) { rkey[n] ^= 0x5c ^ 0x36; + } secp256k1_sha256_write(&hash->inner, rkey, 64); memset(rkey, 0, 64); } @@ -205,15 +207,17 @@ static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha2 static const unsigned char zero[1] = {0x00}; static const unsigned char one[1] = {0x01}; - memset(rng->v, 0x01, 32); - memset(rng->k, 0x00, 32); + memset(rng->v, 0x01, 32); /* RFC6979 3.2.b. */ + memset(rng->k, 0x00, 32); /* RFC6979 3.2.c. */ + /* RFC6979 3.2.d. */ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); secp256k1_hmac_sha256_write(&hmac, rng->v, 32); secp256k1_hmac_sha256_write(&hmac, zero, 1); secp256k1_hmac_sha256_write(&hmac, key, keylen); secp256k1_hmac_sha256_write(&hmac, msg, msglen); if (rnd && rndlen) { + /* RFC6979 3.6 "Additional data". */ secp256k1_hmac_sha256_write(&hmac, rnd, rndlen); } secp256k1_hmac_sha256_finalize(&hmac, rng->k); @@ -221,12 +225,14 @@ static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha2 secp256k1_hmac_sha256_write(&hmac, rng->v, 32); secp256k1_hmac_sha256_finalize(&hmac, rng->v); + /* RFC6979 3.2.f. */ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); secp256k1_hmac_sha256_write(&hmac, rng->v, 32); secp256k1_hmac_sha256_write(&hmac, one, 1); secp256k1_hmac_sha256_write(&hmac, key, keylen); secp256k1_hmac_sha256_write(&hmac, msg, msglen); if (rnd && rndlen) { + /* RFC6979 3.6 "Additional data". */ secp256k1_hmac_sha256_write(&hmac, rnd, rndlen); } secp256k1_hmac_sha256_finalize(&hmac, rng->k); @@ -237,6 +243,7 @@ static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha2 } static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen) { + /* RFC6979 3.2.h. */ static const unsigned char zero[1] = {0x00}; if (rng->retry) { secp256k1_hmac_sha256_t hmac; diff --git a/src/secp256k1/src/num_gmp_impl.h b/src/secp256k1/src/num_gmp_impl.h index 3e4b92d329..dbbc458d5d 100644 --- a/src/secp256k1/src/num_gmp_impl.h +++ b/src/secp256k1/src/num_gmp_impl.h @@ -54,7 +54,9 @@ static void secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, un VERIFY_CHECK(len <= NUM_LIMBS*2); r->limbs = len; r->neg = 0; - while (r->limbs > 1 && r->data[r->limbs-1]==0) r->limbs--; + while (r->limbs > 1 && r->data[r->limbs-1]==0) { + r->limbs--; + } } static void secp256k1_num_add_abs(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { @@ -70,7 +72,9 @@ static void secp256k1_num_sub_abs(secp256k1_num_t *r, const secp256k1_num_t *a, mp_limb_t c = mpn_sub(r->data, a->data, a->limbs, b->data, b->limbs); VERIFY_CHECK(c == 0); r->limbs = a->limbs; - while (r->limbs > 1 && r->data[r->limbs-1]==0) r->limbs--; + while (r->limbs > 1 && r->data[r->limbs-1]==0) { + r->limbs--; + } } static void secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m) { @@ -82,7 +86,9 @@ static void secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m) { mpn_tdiv_qr(t, r->data, 0, r->data, r->limbs, m->data, m->limbs); memset(t, 0, sizeof(t)); r->limbs = m->limbs; - while (r->limbs > 1 && r->data[r->limbs-1]==0) r->limbs--; + while (r->limbs > 1 && r->data[r->limbs-1]==0) { + r->limbs--; + } } if (r->neg && (r->limbs > 1 || r->data[0] != 0)) { @@ -125,7 +131,9 @@ static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t if (sn < 0) { mpn_sub(r->data, m->data, m->limbs, r->data, -sn); r->limbs = m->limbs; - while (r->limbs > 1 && r->data[r->limbs-1]==0) r->limbs--; + while (r->limbs > 1 && r->data[r->limbs-1]==0) { + r->limbs--; + } } else { r->limbs = sn; } @@ -143,15 +151,25 @@ static int secp256k1_num_is_neg(const secp256k1_num_t *a) { } static int secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b) { - if (a->limbs > b->limbs) return 1; - if (a->limbs < b->limbs) return -1; + if (a->limbs > b->limbs) { + return 1; + } + if (a->limbs < b->limbs) { + return -1; + } return mpn_cmp(a->data, b->data, a->limbs); } static int secp256k1_num_eq(const secp256k1_num_t *a, const secp256k1_num_t *b) { - if (a->limbs > b->limbs) return 0; - if (a->limbs < b->limbs) return 0; - if ((a->neg && !secp256k1_num_is_zero(a)) != (b->neg && !secp256k1_num_is_zero(b))) return 0; + if (a->limbs > b->limbs) { + return 0; + } + if (a->limbs < b->limbs) { + return 0; + } + if ((a->neg && !secp256k1_num_is_zero(a)) != (b->neg && !secp256k1_num_is_zero(b))) { + return 0; + } return mpn_cmp(a->data, b->data, a->limbs) == 0; } @@ -198,12 +216,15 @@ static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, cons r->data[0] = 0; return; } - if (a->limbs >= b->limbs) + if (a->limbs >= b->limbs) { mpn_mul(tmp, a->data, a->limbs, b->data, b->limbs); - else + } else { mpn_mul(tmp, b->data, b->limbs, a->data, a->limbs); + } r->limbs = a->limbs + b->limbs; - if (r->limbs > 1 && tmp[r->limbs - 1]==0) r->limbs--; + if (r->limbs > 1 && tmp[r->limbs - 1]==0) { + r->limbs--; + } VERIFY_CHECK(r->limbs <= 2*NUM_LIMBS); mpn_copyi(r->data, tmp, r->limbs); r->neg = a->neg ^ b->neg; @@ -227,7 +248,9 @@ static void secp256k1_num_shift(secp256k1_num_t *r, int bits) { } } } - while (r->limbs>1 && r->data[r->limbs-1]==0) r->limbs--; + while (r->limbs>1 && r->data[r->limbs-1]==0) { + r->limbs--; + } } static void secp256k1_num_negate(secp256k1_num_t *r) { diff --git a/src/secp256k1/src/scalar_impl.h b/src/secp256k1/src/scalar_impl.h index 3acbe264ae..33824983e4 100644 --- a/src/secp256k1/src/scalar_impl.h +++ b/src/secp256k1/src/scalar_impl.h @@ -69,130 +69,168 @@ static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scal secp256k1_scalar_mul(&x8, &x8, x); secp256k1_scalar_sqr(&x15, &x8); - for (i = 0; i < 6; i++) + for (i = 0; i < 6; i++) { secp256k1_scalar_sqr(&x15, &x15); + } secp256k1_scalar_mul(&x15, &x15, &x7); secp256k1_scalar_sqr(&x30, &x15); - for (i = 0; i < 14; i++) + for (i = 0; i < 14; i++) { secp256k1_scalar_sqr(&x30, &x30); + } secp256k1_scalar_mul(&x30, &x30, &x15); secp256k1_scalar_sqr(&x60, &x30); - for (i = 0; i < 29; i++) + for (i = 0; i < 29; i++) { secp256k1_scalar_sqr(&x60, &x60); + } secp256k1_scalar_mul(&x60, &x60, &x30); secp256k1_scalar_sqr(&x120, &x60); - for (i = 0; i < 59; i++) + for (i = 0; i < 59; i++) { secp256k1_scalar_sqr(&x120, &x120); + } secp256k1_scalar_mul(&x120, &x120, &x60); secp256k1_scalar_sqr(&x127, &x120); - for (i = 0; i < 6; i++) + for (i = 0; i < 6; i++) { secp256k1_scalar_sqr(&x127, &x127); + } secp256k1_scalar_mul(&x127, &x127, &x7); /* Then accumulate the final result (t starts at x127). */ t = &x127; - for (i = 0; i < 2; i++) /* 0 */ + for (i = 0; i < 2; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 4; i++) /* 0 */ + for (i = 0; i < 4; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 2; i++) /* 0 */ + for (i = 0; i < 2; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 2; i++) /* 0 */ + for (i = 0; i < 2; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 2; i++) /* 0 */ + for (i = 0; i < 2; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 4; i++) /* 0 */ + for (i = 0; i < 4; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 3; i++) /* 0 */ + for (i = 0; i < 3; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 4; i++) /* 0 */ + for (i = 0; i < 4; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 5; i++) /* 00 */ + for (i = 0; i < 5; i++) { /* 00 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 4; i++) /* 00 */ + for (i = 0; i < 4; i++) { /* 00 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 2; i++) /* 0 */ + for (i = 0; i < 2; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 2; i++) /* 0 */ + for (i = 0; i < 2; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 5; i++) /* 0 */ + for (i = 0; i < 5; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x4); /* 1111 */ - for (i = 0; i < 2; i++) /* 0 */ + for (i = 0; i < 2; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 3; i++) /* 00 */ + for (i = 0; i < 3; i++) { /* 00 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 4; i++) /* 000 */ + for (i = 0; i < 4; i++) { /* 000 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 2; i++) /* 0 */ + for (i = 0; i < 2; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 10; i++) /* 0000000 */ + for (i = 0; i < 10; i++) { /* 0000000 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 4; i++) /* 0 */ + for (i = 0; i < 4; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 9; i++) /* 0 */ + for (i = 0; i < 9; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x8); /* 11111111 */ - for (i = 0; i < 2; i++) /* 0 */ + for (i = 0; i < 2; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 3; i++) /* 00 */ + for (i = 0; i < 3; i++) { /* 00 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 3; i++) /* 00 */ + for (i = 0; i < 3; i++) { /* 00 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 5; i++) /* 0 */ + for (i = 0; i < 5; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x4); /* 1111 */ - for (i = 0; i < 2; i++) /* 0 */ + for (i = 0; i < 2; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 5; i++) /* 000 */ + for (i = 0; i < 5; i++) { /* 000 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 4; i++) /* 00 */ + for (i = 0; i < 4; i++) { /* 00 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 2; i++) /* 0 */ + for (i = 0; i < 2; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 8; i++) /* 000000 */ + for (i = 0; i < 8; i++) { /* 000000 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 3; i++) /* 0 */ + for (i = 0; i < 3; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 3; i++) /* 00 */ + for (i = 0; i < 3; i++) { /* 00 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 6; i++) /* 00000 */ + for (i = 0; i < 6; i++) { /* 00000 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 8; i++) /* 00 */ + for (i = 0; i < 8; i++) { /* 00 */ secp256k1_scalar_sqr(t, t); + } secp256k1_scalar_mul(r, t, &x6); /* 111111 */ } diff --git a/src/secp256k1/src/secp256k1.c b/src/secp256k1/src/secp256k1.c index 8c4eca4b62..d6192dc4ed 100644 --- a/src/secp256k1/src/secp256k1.c +++ b/src/secp256k1/src/secp256k1.c @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * + * Copyright (c) 2013-2015 Pieter Wuille * * Distributed under the MIT software license, see the accompanying * * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ @@ -19,26 +19,48 @@ #include "eckey_impl.h" #include "hash_impl.h" -void secp256k1_start(unsigned int flags) { - if (flags & SECP256K1_START_SIGN) { - secp256k1_ecmult_gen_start(); +struct secp256k1_context_struct { + secp256k1_ecmult_context_t ecmult_ctx; + secp256k1_ecmult_gen_context_t ecmult_gen_ctx; +}; + +secp256k1_context_t* secp256k1_context_create(int flags) { + secp256k1_context_t* ret = (secp256k1_context_t*)checked_malloc(sizeof(secp256k1_context_t)); + + secp256k1_ecmult_context_init(&ret->ecmult_ctx); + secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx); + + if (flags & SECP256K1_CONTEXT_SIGN) { + secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx); } - if (flags & SECP256K1_START_VERIFY) { - secp256k1_ecmult_start(); + if (flags & SECP256K1_CONTEXT_VERIFY) { + secp256k1_ecmult_context_build(&ret->ecmult_ctx); } + + return ret; } -void secp256k1_stop(void) { - secp256k1_ecmult_stop(); - secp256k1_ecmult_gen_stop(); +secp256k1_context_t* secp256k1_context_clone(const secp256k1_context_t* ctx) { + secp256k1_context_t* ret = (secp256k1_context_t*)checked_malloc(sizeof(secp256k1_context_t)); + secp256k1_ecmult_context_clone(&ret->ecmult_ctx, &ctx->ecmult_ctx); + secp256k1_ecmult_gen_context_clone(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx); + return ret; } -int secp256k1_ecdsa_verify(const unsigned char *msg32, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) { +void secp256k1_context_destroy(secp256k1_context_t* ctx) { + secp256k1_ecmult_context_clear(&ctx->ecmult_ctx); + secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); + + free(ctx); +} + +int secp256k1_ecdsa_verify(const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) { secp256k1_ge_t q; secp256k1_ecdsa_sig_t s; secp256k1_scalar_t m; int ret = -3; - DEBUG_CHECK(secp256k1_ecmult_consts != NULL); + DEBUG_CHECK(ctx != NULL); + DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); DEBUG_CHECK(msg32 != NULL); DEBUG_CHECK(sig != NULL); DEBUG_CHECK(pubkey != NULL); @@ -47,7 +69,7 @@ int secp256k1_ecdsa_verify(const unsigned char *msg32, const unsigned char *sig, if (secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen)) { if (secp256k1_ecdsa_sig_parse(&s, sig, siglen)) { - if (secp256k1_ecdsa_sig_verify(&s, &q, &m)) { + if (secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &s, &q, &m)) { /* success is 1, all other values are fail */ ret = 1; } else { @@ -66,7 +88,7 @@ int secp256k1_ecdsa_verify(const unsigned char *msg32, const unsigned char *sig, static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { secp256k1_rfc6979_hmac_sha256_t rng; unsigned int i; - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key32, 32, msg32, 32, data, data != NULL ? 32 : 0); + secp256k1_rfc6979_hmac_sha256_initialize(&rng, key32, 32, msg32, 32, (const unsigned char*)data, data != NULL ? 32 : 0); for (i = 0; i <= counter; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); } @@ -77,13 +99,14 @@ static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *m const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979; const secp256k1_nonce_function_t secp256k1_nonce_function_default = nonce_function_rfc6979; -int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) { +int secp256k1_ecdsa_sign(const secp256k1_context_t* ctx, const unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) { secp256k1_ecdsa_sig_t sig; secp256k1_scalar_t sec, non, msg; int ret = 0; int overflow = 0; unsigned int count = 0; - DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL); + DEBUG_CHECK(ctx != NULL); + DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); DEBUG_CHECK(msg32 != NULL); DEBUG_CHECK(signature != NULL); DEBUG_CHECK(signaturelen != NULL); @@ -105,7 +128,7 @@ int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, i secp256k1_scalar_set_b32(&non, nonce32, &overflow); memset(nonce32, 0, 32); if (!secp256k1_scalar_is_zero(&non) && !overflow) { - if (secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, NULL)) { + if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &sig, &sec, &msg, &non, NULL)) { break; } } @@ -124,13 +147,14 @@ int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, i return ret; } -int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata, int *recid) { +int secp256k1_ecdsa_sign_compact(const secp256k1_context_t* ctx, const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata, int *recid) { secp256k1_ecdsa_sig_t sig; secp256k1_scalar_t sec, non, msg; int ret = 0; int overflow = 0; unsigned int count = 0; - DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL); + DEBUG_CHECK(ctx != NULL); + DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); DEBUG_CHECK(msg32 != NULL); DEBUG_CHECK(sig64 != NULL); DEBUG_CHECK(seckey != NULL); @@ -151,7 +175,7 @@ int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig6 secp256k1_scalar_set_b32(&non, nonce32, &overflow); memset(nonce32, 0, 32); if (!secp256k1_scalar_is_zero(&non) && !overflow) { - if (secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, recid)) { + if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &sig, &sec, &msg, &non, recid)) { break; } } @@ -171,13 +195,14 @@ int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig6 return ret; } -int secp256k1_ecdsa_recover_compact(const unsigned char *msg32, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) { +int secp256k1_ecdsa_recover_compact(const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) { secp256k1_ge_t q; secp256k1_ecdsa_sig_t sig; secp256k1_scalar_t m; int ret = 0; int overflow = 0; - DEBUG_CHECK(secp256k1_ecmult_consts != NULL); + DEBUG_CHECK(ctx != NULL); + DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); DEBUG_CHECK(msg32 != NULL); DEBUG_CHECK(sig64 != NULL); DEBUG_CHECK(pubkey != NULL); @@ -190,7 +215,7 @@ int secp256k1_ecdsa_recover_compact(const unsigned char *msg32, const unsigned c if (!overflow) { secp256k1_scalar_set_b32(&m, msg32, NULL); - if (secp256k1_ecdsa_sig_recover(&sig, &q, &m, recid)) { + if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &sig, &q, &m, recid)) { ret = secp256k1_eckey_pubkey_serialize(&q, pubkey, pubkeylen, compressed); } } @@ -198,11 +223,13 @@ int secp256k1_ecdsa_recover_compact(const unsigned char *msg32, const unsigned c return ret; } -int secp256k1_ec_seckey_verify(const unsigned char *seckey) { +int secp256k1_ec_seckey_verify(const secp256k1_context_t* ctx, const unsigned char *seckey) { secp256k1_scalar_t sec; int ret; int overflow; + DEBUG_CHECK(ctx != NULL); DEBUG_CHECK(seckey != NULL); + (void)ctx; secp256k1_scalar_set_b32(&sec, seckey, &overflow); ret = !secp256k1_scalar_is_zero(&sec) && !overflow; @@ -210,27 +237,30 @@ int secp256k1_ec_seckey_verify(const unsigned char *seckey) { return ret; } -int secp256k1_ec_pubkey_verify(const unsigned char *pubkey, int pubkeylen) { +int secp256k1_ec_pubkey_verify(const secp256k1_context_t* ctx, const unsigned char *pubkey, int pubkeylen) { secp256k1_ge_t q; + DEBUG_CHECK(ctx != NULL); DEBUG_CHECK(pubkey != NULL); + (void)ctx; return secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen); } -int secp256k1_ec_pubkey_create(unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed) { +int secp256k1_ec_pubkey_create(const secp256k1_context_t* ctx, unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed) { secp256k1_gej_t pj; secp256k1_ge_t p; secp256k1_scalar_t sec; int overflow; int ret = 0; - DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL); + DEBUG_CHECK(ctx != NULL); + DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); DEBUG_CHECK(pubkey != NULL); DEBUG_CHECK(pubkeylen != NULL); DEBUG_CHECK(seckey != NULL); secp256k1_scalar_set_b32(&sec, seckey, &overflow); if (!overflow) { - secp256k1_ecmult_gen(&pj, &sec); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pj, &sec); secp256k1_scalar_clear(&sec); secp256k1_ge_set_gej(&p, &pj); ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, compressed); @@ -241,11 +271,12 @@ int secp256k1_ec_pubkey_create(unsigned char *pubkey, int *pubkeylen, const unsi return ret; } -int secp256k1_ec_pubkey_decompress(unsigned char *pubkey, int *pubkeylen) { +int secp256k1_ec_pubkey_decompress(const secp256k1_context_t* ctx, unsigned char *pubkey, int *pubkeylen) { secp256k1_ge_t p; int ret = 0; DEBUG_CHECK(pubkey != NULL); DEBUG_CHECK(pubkeylen != NULL); + (void)ctx; if (secp256k1_eckey_pubkey_parse(&p, pubkey, *pubkeylen)) { ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, 0); @@ -253,13 +284,15 @@ int secp256k1_ec_pubkey_decompress(unsigned char *pubkey, int *pubkeylen) { return ret; } -int secp256k1_ec_privkey_tweak_add(unsigned char *seckey, const unsigned char *tweak) { +int secp256k1_ec_privkey_tweak_add(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *tweak) { secp256k1_scalar_t term; secp256k1_scalar_t sec; int ret = 0; int overflow = 0; + DEBUG_CHECK(ctx != NULL); DEBUG_CHECK(seckey != NULL); DEBUG_CHECK(tweak != NULL); + (void)ctx; secp256k1_scalar_set_b32(&term, tweak, &overflow); secp256k1_scalar_set_b32(&sec, seckey, NULL); @@ -274,12 +307,13 @@ int secp256k1_ec_privkey_tweak_add(unsigned char *seckey, const unsigned char *t return ret; } -int secp256k1_ec_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { +int secp256k1_ec_pubkey_tweak_add(const secp256k1_context_t* ctx, unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { secp256k1_ge_t p; secp256k1_scalar_t term; int ret = 0; int overflow = 0; - DEBUG_CHECK(secp256k1_ecmult_consts != NULL); + DEBUG_CHECK(ctx != NULL); + DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); DEBUG_CHECK(pubkey != NULL); DEBUG_CHECK(tweak != NULL); @@ -287,7 +321,7 @@ int secp256k1_ec_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const un if (!overflow) { ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); if (ret) { - ret = secp256k1_eckey_pubkey_tweak_add(&p, &term); + ret = secp256k1_eckey_pubkey_tweak_add(&ctx->ecmult_ctx, &p, &term); } if (ret) { int oldlen = pubkeylen; @@ -299,13 +333,15 @@ int secp256k1_ec_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const un return ret; } -int secp256k1_ec_privkey_tweak_mul(unsigned char *seckey, const unsigned char *tweak) { +int secp256k1_ec_privkey_tweak_mul(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *tweak) { secp256k1_scalar_t factor; secp256k1_scalar_t sec; int ret = 0; int overflow = 0; + DEBUG_CHECK(ctx != NULL); DEBUG_CHECK(seckey != NULL); DEBUG_CHECK(tweak != NULL); + (void)ctx; secp256k1_scalar_set_b32(&factor, tweak, &overflow); secp256k1_scalar_set_b32(&sec, seckey, NULL); @@ -319,12 +355,13 @@ int secp256k1_ec_privkey_tweak_mul(unsigned char *seckey, const unsigned char *t return ret; } -int secp256k1_ec_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { +int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context_t* ctx, unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { secp256k1_ge_t p; secp256k1_scalar_t factor; int ret = 0; int overflow = 0; - DEBUG_CHECK(secp256k1_ecmult_consts != NULL); + DEBUG_CHECK(ctx != NULL); + DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); DEBUG_CHECK(pubkey != NULL); DEBUG_CHECK(tweak != NULL); @@ -332,7 +369,7 @@ int secp256k1_ec_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const un if (!overflow) { ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); if (ret) { - ret = secp256k1_eckey_pubkey_tweak_mul(&p, &factor); + ret = secp256k1_eckey_pubkey_tweak_mul(&ctx->ecmult_ctx, &p, &factor); } if (ret) { int oldlen = pubkeylen; @@ -344,24 +381,27 @@ int secp256k1_ec_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const un return ret; } -int secp256k1_ec_privkey_export(const unsigned char *seckey, unsigned char *privkey, int *privkeylen, int compressed) { +int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, const unsigned char *seckey, unsigned char *privkey, int *privkeylen, int compressed) { secp256k1_scalar_t key; int ret = 0; DEBUG_CHECK(seckey != NULL); DEBUG_CHECK(privkey != NULL); DEBUG_CHECK(privkeylen != NULL); + DEBUG_CHECK(ctx != NULL); + DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); secp256k1_scalar_set_b32(&key, seckey, NULL); - ret = secp256k1_eckey_privkey_serialize(privkey, privkeylen, &key, compressed); + ret = secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, privkeylen, &key, compressed); secp256k1_scalar_clear(&key); return ret; } -int secp256k1_ec_privkey_import(unsigned char *seckey, const unsigned char *privkey, int privkeylen) { +int secp256k1_ec_privkey_import(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *privkey, int privkeylen) { secp256k1_scalar_t key; int ret = 0; DEBUG_CHECK(seckey != NULL); DEBUG_CHECK(privkey != NULL); + (void)ctx; ret = secp256k1_eckey_privkey_parse(&key, privkey, privkeylen); if (ret) { @@ -370,3 +410,10 @@ int secp256k1_ec_privkey_import(unsigned char *seckey, const unsigned char *priv secp256k1_scalar_clear(&key); return ret; } + +int secp256k1_context_randomize(secp256k1_context_t* ctx, const unsigned char *seed32) { + DEBUG_CHECK(ctx != NULL); + DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); + return 1; +} diff --git a/src/secp256k1/src/tests.c b/src/secp256k1/src/tests.c index f7f1acac64..d0e05057f2 100644 --- a/src/secp256k1/src/tests.c +++ b/src/secp256k1/src/tests.c @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * + * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * * Distributed under the MIT software license, see the accompanying * * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ @@ -24,6 +24,7 @@ #endif static int count = 64; +static secp256k1_context_t *ctx = NULL; void random_field_element_test(secp256k1_fe_t *fe) { do { @@ -55,8 +56,9 @@ void random_group_element_test(secp256k1_ge_t *ge) { secp256k1_fe_t fe; do { random_field_element_test(&fe); - if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_rand32() & 1)) + if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_rand32() & 1)) { break; + } } while(1); } @@ -81,8 +83,9 @@ void random_scalar_order_test(secp256k1_scalar_t *num) { int overflow = 0; secp256k1_rand256_test(b32); secp256k1_scalar_set_b32(num, b32, &overflow); - if (overflow || secp256k1_scalar_is_zero(num)) + if (overflow || secp256k1_scalar_is_zero(num)) { continue; + } break; } while(1); } @@ -93,12 +96,60 @@ void random_scalar_order(secp256k1_scalar_t *num) { int overflow = 0; secp256k1_rand256(b32); secp256k1_scalar_set_b32(num, b32, &overflow); - if (overflow || secp256k1_scalar_is_zero(num)) + if (overflow || secp256k1_scalar_is_zero(num)) { continue; + } break; } while(1); } +void run_context_tests(void) { + secp256k1_context_t *none = secp256k1_context_create(0); + secp256k1_context_t *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); + secp256k1_context_t *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); + secp256k1_context_t *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + + secp256k1_gej_t pubj; + secp256k1_ge_t pub; + secp256k1_scalar_t msg, key, nonce; + secp256k1_ecdsa_sig_t sig; + + /*** clone and destroy all of them to make sure cloning was complete ***/ + { + secp256k1_context_t *ctx_tmp; + + ctx_tmp = none; none = secp256k1_context_clone(none); secp256k1_context_destroy(ctx_tmp); + ctx_tmp = sign; sign = secp256k1_context_clone(sign); secp256k1_context_destroy(ctx_tmp); + ctx_tmp = vrfy; vrfy = secp256k1_context_clone(vrfy); secp256k1_context_destroy(ctx_tmp); + ctx_tmp = both; both = secp256k1_context_clone(both); secp256k1_context_destroy(ctx_tmp); + } + + /*** attempt to use them ***/ + random_scalar_order_test(&msg); + random_scalar_order_test(&key); + secp256k1_ecmult_gen(&both->ecmult_gen_ctx, &pubj, &key); + secp256k1_ge_set_gej(&pub, &pubj); + + /* obtain a working nonce */ + do { + random_scalar_order_test(&nonce); + } while(!secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL)); + + /* try signing */ + CHECK(secp256k1_ecdsa_sig_sign(&sign->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL)); + CHECK(secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL)); + + /* try verifying */ + CHECK(secp256k1_ecdsa_sig_verify(&vrfy->ecmult_ctx, &sig, &pub, &msg)); + CHECK(secp256k1_ecdsa_sig_verify(&both->ecmult_ctx, &sig, &pub, &msg)); + + /* cleanup */ + secp256k1_context_destroy(none); + secp256k1_context_destroy(sign); + secp256k1_context_destroy(vrfy); + secp256k1_context_destroy(both); +} + /***** HASH TESTS *****/ void run_sha256_tests(void) { @@ -229,8 +280,9 @@ void run_rfc6979_hmac_sha256_tests(void) { #ifndef USE_NUM_NONE void random_num_negate(secp256k1_num_t *num) { - if (secp256k1_rand32() & 1) + if (secp256k1_rand32() & 1) { secp256k1_num_negate(num); + } } void random_num_order_test(secp256k1_num_t *num) { @@ -624,8 +676,9 @@ void random_fe_non_zero(secp256k1_fe_t *nz) { while (--tries >= 0) { random_fe(nz); secp256k1_fe_normalize(nz); - if (!secp256k1_fe_is_zero(nz)) + if (!secp256k1_fe_is_zero(nz)) { break; + } } /* Infinitesimal probability of spurious failure here */ CHECK(tries >= 0); @@ -700,12 +753,22 @@ void run_field_misc(void) { CHECK(secp256k1_fe_equal_var(&x, &x)); z = x; secp256k1_fe_add(&z,&y); - secp256k1_fe_normalize(&z); + /* Test fe conditional move; z is not normalized here. */ + q = x; + secp256k1_fe_cmov(&x, &z, 0); + secp256k1_fe_cmov(&x, &x, 1); + CHECK(memcmp(&x, &z, sizeof(x)) != 0); + CHECK(memcmp(&x, &q, sizeof(x)) == 0); + secp256k1_fe_cmov(&q, &z, 1); + CHECK(memcmp(&q, &z, sizeof(q)) == 0); /* Test storage conversion and conditional moves. */ + secp256k1_fe_normalize(&z); + CHECK(!secp256k1_fe_equal_var(&x, &z)); secp256k1_fe_to_storage(&xs, &x); secp256k1_fe_to_storage(&ys, &y); secp256k1_fe_to_storage(&zs, &z); secp256k1_fe_storage_cmov(&zs, &xs, 0); + secp256k1_fe_storage_cmov(&zs, &zs, 1); CHECK(memcmp(&xs, &zs, sizeof(xs)) != 0); secp256k1_fe_storage_cmov(&ys, &xs, 1); CHECK(memcmp(&xs, &ys, sizeof(xs)) == 0); @@ -765,14 +828,17 @@ void run_field_inv_all_var(void) { for (i = 0; i < count; i++) { size_t j; size_t len = (secp256k1_rand32() & 15) + 1; - for (j = 0; j < len; j++) + for (j = 0; j < len; j++) { random_fe_non_zero(&x[j]); + } secp256k1_fe_inv_all_var(len, xi, x); - for (j = 0; j < len; j++) + for (j = 0; j < len; j++) { CHECK(check_fe_inverse(&x[j], &xi[j])); + } secp256k1_fe_inv_all_var(len, xii, xi); - for (j = 0; j < len; j++) + for (j = 0; j < len; j++) { CHECK(check_fe_equal(&x[j], &xii[j])); + } } } @@ -844,18 +910,42 @@ void run_sqrt(void) { void ge_equals_ge(const secp256k1_ge_t *a, const secp256k1_ge_t *b) { CHECK(a->infinity == b->infinity); - if (a->infinity) + if (a->infinity) { return; + } CHECK(secp256k1_fe_equal_var(&a->x, &b->x)); CHECK(secp256k1_fe_equal_var(&b->y, &b->y)); } +/* This compares jacobian points including their Z, not just their geometric meaning. */ +int gej_xyz_equals_gej(const secp256k1_gej_t *a, const secp256k1_gej_t *b) { + secp256k1_gej_t a2; + secp256k1_gej_t b2; + int ret = 1; + ret &= a->infinity == b->infinity; + if (ret && !a->infinity) { + a2 = *a; + b2 = *b; + secp256k1_fe_normalize(&a2.x); + secp256k1_fe_normalize(&a2.y); + secp256k1_fe_normalize(&a2.z); + secp256k1_fe_normalize(&b2.x); + secp256k1_fe_normalize(&b2.y); + secp256k1_fe_normalize(&b2.z); + ret &= secp256k1_fe_cmp_var(&a2.x, &b2.x) == 0; + ret &= secp256k1_fe_cmp_var(&a2.y, &b2.y) == 0; + ret &= secp256k1_fe_cmp_var(&a2.z, &b2.z) == 0; + } + return ret; +} + void ge_equals_gej(const secp256k1_ge_t *a, const secp256k1_gej_t *b) { secp256k1_fe_t z2s; secp256k1_fe_t u1, u2, s1, s2; CHECK(a->infinity == b->infinity); - if (a->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); @@ -874,8 +964,8 @@ void test_ge(void) { * All magnitudes are randomized. * All 17*17 combinations of points are added to eachother, using all applicable methods. */ - secp256k1_ge_t *ge = malloc(sizeof(secp256k1_ge_t) * (1 + 4 * runs)); - secp256k1_gej_t *gej = malloc(sizeof(secp256k1_gej_t) * (1 + 4 * runs)); + secp256k1_ge_t *ge = (secp256k1_ge_t *)malloc(sizeof(secp256k1_ge_t) * (1 + 4 * runs)); + secp256k1_gej_t *gej = (secp256k1_gej_t *)malloc(sizeof(secp256k1_gej_t) * (1 + 4 * runs)); secp256k1_gej_set_infinity(&gej[0]); secp256k1_ge_clear(&ge[0]); secp256k1_ge_set_gej_var(&ge[0], &gej[0]); @@ -951,7 +1041,7 @@ void test_ge(void) { /* Test adding all points together in random order equals infinity. */ { secp256k1_gej_t sum = SECP256K1_GEJ_CONST_INFINITY; - secp256k1_gej_t *gej_shuffled = malloc((4 * runs + 1) * sizeof(secp256k1_gej_t)); + secp256k1_gej_t *gej_shuffled = (secp256k1_gej_t *)malloc((4 * runs + 1) * sizeof(secp256k1_gej_t)); for (i = 0; i < 4 * runs + 1; i++) { gej_shuffled[i] = gej[i]; } @@ -972,9 +1062,12 @@ void test_ge(void) { /* Test batch gej -> ge conversion. */ { - secp256k1_ge_t *ge_set_all = malloc((4 * runs + 1) * sizeof(secp256k1_ge_t)); + secp256k1_ge_t *ge_set_all = (secp256k1_ge_t *)malloc((4 * runs + 1) * sizeof(secp256k1_ge_t)); secp256k1_ge_set_all_gej_var(4 * runs + 1, ge_set_all, gej); for (i = 0; i < 4 * runs + 1; i++) { + secp256k1_fe_t s; + random_fe_non_zero(&s); + secp256k1_gej_rescale(&gej[i], &s); ge_equals_gej(&ge_set_all[i], &gej[i]); } free(ge_set_all); @@ -1025,7 +1118,7 @@ void run_ecmult_chain(void) { x = a; for (i = 0; i < 200*count; i++) { /* in each iteration, compute X = xn*X + gn*G; */ - secp256k1_ecmult(&x, &x, &xn, &gn); + secp256k1_ecmult(&ctx->ecmult_ctx, &x, &x, &xn, &gn); /* also compute ae and ge: the actual accumulated factors for A and G */ /* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */ secp256k1_scalar_mul(&ae, &ae, &xn); @@ -1051,7 +1144,7 @@ void run_ecmult_chain(void) { } } /* redo the computation, but directly with the resulting ae and ge coefficients: */ - secp256k1_ecmult(&x2, &a, &ae, &ge); + secp256k1_ecmult(&ctx->ecmult_ctx, &x2, &a, &ae, &ge); secp256k1_gej_neg(&x2, &x2); secp256k1_gej_add_var(&x2, &x2, &x); CHECK(secp256k1_gej_is_infinity(&x2)); @@ -1067,8 +1160,8 @@ void test_point_times_order(const secp256k1_gej_t *point) { int psize = 65; random_scalar_order_test(&x); secp256k1_scalar_negate(&nx, &x); - secp256k1_ecmult(&res1, point, &x, &x); /* calc res1 = x * point + x * G; */ - secp256k1_ecmult(&res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */ + secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &x, &x); /* calc res1 = x * point + x * G; */ + secp256k1_ecmult(&ctx->ecmult_ctx, &res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */ secp256k1_gej_add_var(&res1, &res1, &res2); CHECK(secp256k1_gej_is_infinity(&res1)); CHECK(secp256k1_gej_is_valid_var(&res1) == 0); @@ -1141,17 +1234,96 @@ void run_wnaf(void) { secp256k1_scalar_t n; for (i = 0; i < count; i++) { random_scalar_order(&n); - if (i % 1) - secp256k1_scalar_negate(&n, &n); test_wnaf(&n, 4+(i%10)); } } +void test_ecmult_constants(void) { + /* Test ecmult_gen() for [0..36) and [order-36..0). */ + secp256k1_scalar_t x; + secp256k1_gej_t r; + secp256k1_ge_t ng; + int i; + int j; + secp256k1_ge_neg(&ng, &secp256k1_ge_const_g); + for (i = 0; i < 36; i++ ) { + secp256k1_scalar_set_int(&x, i); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &r, &x); + for (j = 0; j < i; j++) { + if (j == i - 1) { + ge_equals_gej(&secp256k1_ge_const_g, &r); + } + secp256k1_gej_add_ge(&r, &r, &ng); + } + CHECK(secp256k1_gej_is_infinity(&r)); + } + for (i = 1; i <= 36; i++ ) { + secp256k1_scalar_set_int(&x, i); + secp256k1_scalar_negate(&x, &x); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &r, &x); + for (j = 0; j < i; j++) { + if (j == i - 1) { + ge_equals_gej(&ng, &r); + } + secp256k1_gej_add_ge(&r, &r, &secp256k1_ge_const_g); + } + CHECK(secp256k1_gej_is_infinity(&r)); + } +} + +void run_ecmult_constants(void) { + test_ecmult_constants(); +} + +void test_ecmult_gen_blind(void) { + /* Test ecmult_gen() blinding and confirm that the blinding changes, the affline points match, and the z's don't match. */ + secp256k1_scalar_t key; + secp256k1_scalar_t b; + unsigned char seed32[32]; + secp256k1_gej_t pgej; + secp256k1_gej_t pgej2; + secp256k1_gej_t i; + secp256k1_ge_t pge; + random_scalar_order_test(&key); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pgej, &key); + secp256k1_rand256(seed32); + b = ctx->ecmult_gen_ctx.blind; + i = ctx->ecmult_gen_ctx.initial; + secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); + CHECK(!secp256k1_scalar_eq(&b, &ctx->ecmult_gen_ctx.blind)); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pgej2, &key); + CHECK(!gej_xyz_equals_gej(&pgej, &pgej2)); + CHECK(!gej_xyz_equals_gej(&i, &ctx->ecmult_gen_ctx.initial)); + secp256k1_ge_set_gej(&pge, &pgej); + ge_equals_gej(&pge, &pgej2); +} + +void test_ecmult_gen_blind_reset(void) { + /* Test ecmult_gen() blinding reset and confirm that the blinding is consistent. */ + secp256k1_scalar_t b; + secp256k1_gej_t initial; + secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, 0); + b = ctx->ecmult_gen_ctx.blind; + initial = ctx->ecmult_gen_ctx.initial; + secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, 0); + CHECK(secp256k1_scalar_eq(&b, &ctx->ecmult_gen_ctx.blind)); + CHECK(gej_xyz_equals_gej(&initial, &ctx->ecmult_gen_ctx.initial)); +} + +void run_ecmult_gen_blind(void) { + int i; + test_ecmult_gen_blind_reset(); + for (i = 0; i < 10; i++) { + test_ecmult_gen_blind(); + } +} + + void random_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *key, const secp256k1_scalar_t *msg, int *recid) { secp256k1_scalar_t nonce; do { random_scalar_order_test(&nonce); - } while(!secp256k1_ecdsa_sig_sign(sig, key, msg, &nonce, recid)); + } while(!secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, sig, key, msg, &nonce, recid)); } void test_ecdsa_sign_verify(void) { @@ -1164,15 +1336,17 @@ void test_ecdsa_sign_verify(void) { int getrec; random_scalar_order_test(&msg); random_scalar_order_test(&key); - secp256k1_ecmult_gen(&pubj, &key); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubj, &key); secp256k1_ge_set_gej(&pub, &pubj); getrec = secp256k1_rand32()&1; random_sign(&sig, &key, &msg, getrec?&recid:NULL); - if (getrec) CHECK(recid >= 0 && recid < 4); - CHECK(secp256k1_ecdsa_sig_verify(&sig, &pub, &msg)); + if (getrec) { + CHECK(recid >= 0 && recid < 4); + } + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &pub, &msg)); secp256k1_scalar_set_int(&one, 1); secp256k1_scalar_add(&msg, &msg, &one); - CHECK(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg)); + CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &pub, &msg)); } void run_ecdsa_sign_verify(void) { @@ -1192,7 +1366,9 @@ static int precomputed_nonce_function(unsigned char *nonce32, const unsigned cha static int nonce_function_test_fail(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { /* Dummy nonce generator that has a fatal error on the first counter value. */ - if (counter == 0) return 0; + if (counter == 0) { + return 0; + } return nonce_function_rfc6979(nonce32, msg32, key32, counter - 1, data); } @@ -1200,7 +1376,9 @@ static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char /* Dummy nonce generator that produces unacceptable nonces for the first several counter values. */ if (counter < 3) { memset(nonce32, counter==0 ? 0 : 255, 32); - if (counter == 2) nonce32[31]--; + if (counter == 2) { + nonce32[31]--; + } return 1; } if (counter < 5) { @@ -1211,12 +1389,16 @@ static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 }; memcpy(nonce32, order, 32); - if (counter == 4) nonce32[31]++; + if (counter == 4) { + nonce32[31]++; + } return 1; } /* Retry rate of 6979 is negligible esp. as we only call this in determinstic tests. */ /* If someone does fine a case where it retries for secp256k1, we'd like to know. */ - if (counter > 5) return 0; + if (counter > 5) { + return 0; + } return nonce_function_rfc6979(nonce32, msg32, key32, counter - 5, data); } @@ -1257,16 +1439,16 @@ void test_ecdsa_end_to_end(void) { } /* Construct and verify corresponding public key. */ - CHECK(secp256k1_ec_seckey_verify(privkey) == 1); - CHECK(secp256k1_ec_pubkey_create(pubkey, &pubkeylen, privkey, (secp256k1_rand32() & 3) != 0) == 1); + CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); + CHECK(secp256k1_ec_pubkey_create(ctx, pubkey, &pubkeylen, privkey, (secp256k1_rand32() & 3) != 0) == 1); if (secp256k1_rand32() & 1) { - CHECK(secp256k1_ec_pubkey_decompress(pubkey, &pubkeylen)); + CHECK(secp256k1_ec_pubkey_decompress(ctx, pubkey, &pubkeylen)); } - CHECK(secp256k1_ec_pubkey_verify(pubkey, pubkeylen)); + CHECK(secp256k1_ec_pubkey_verify(ctx, pubkey, pubkeylen)); /* Verify private key import and export. */ - CHECK(secp256k1_ec_privkey_export(privkey, seckey, &seckeylen, secp256k1_rand32() % 2) == 1); - CHECK(secp256k1_ec_privkey_import(privkey2, seckey, seckeylen) == 1); + CHECK(secp256k1_ec_privkey_export(ctx, privkey, seckey, &seckeylen, secp256k1_rand32() % 2) == 1); + CHECK(secp256k1_ec_privkey_import(ctx, privkey2, seckey, seckeylen) == 1); CHECK(memcmp(privkey, privkey2, 32) == 0); /* Optionally tweak the keys using addition. */ @@ -1277,11 +1459,13 @@ void test_ecdsa_end_to_end(void) { unsigned char pubkey2[65]; int pubkeylen2 = 65; secp256k1_rand256_test(rnd); - ret1 = secp256k1_ec_privkey_tweak_add(privkey, rnd); - ret2 = secp256k1_ec_pubkey_tweak_add(pubkey, pubkeylen, rnd); + ret1 = secp256k1_ec_privkey_tweak_add(ctx, privkey, rnd); + ret2 = secp256k1_ec_pubkey_tweak_add(ctx, pubkey, pubkeylen, rnd); CHECK(ret1 == ret2); - if (ret1 == 0) return; - CHECK(secp256k1_ec_pubkey_create(pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); + if (ret1 == 0) { + return; + } + CHECK(secp256k1_ec_pubkey_create(ctx, pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0); } @@ -1293,25 +1477,27 @@ void test_ecdsa_end_to_end(void) { unsigned char pubkey2[65]; int pubkeylen2 = 65; secp256k1_rand256_test(rnd); - ret1 = secp256k1_ec_privkey_tweak_mul(privkey, rnd); - ret2 = secp256k1_ec_pubkey_tweak_mul(pubkey, pubkeylen, rnd); + ret1 = secp256k1_ec_privkey_tweak_mul(ctx, privkey, rnd); + ret2 = secp256k1_ec_pubkey_tweak_mul(ctx, pubkey, pubkeylen, rnd); CHECK(ret1 == ret2); - if (ret1 == 0) return; - CHECK(secp256k1_ec_pubkey_create(pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); + if (ret1 == 0) { + return; + } + CHECK(secp256k1_ec_pubkey_create(ctx, pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0); } /* Sign. */ - CHECK(secp256k1_ecdsa_sign(message, signature, &signaturelen, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, message, signature, &signaturelen, privkey, NULL, NULL) == 1); CHECK(signaturelen > 0); - CHECK(secp256k1_ecdsa_sign(message, signature2, &signaturelen2, privkey, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, message, signature2, &signaturelen2, privkey, NULL, extra) == 1); CHECK(signaturelen2 > 0); extra[31] = 1; - CHECK(secp256k1_ecdsa_sign(message, signature3, &signaturelen3, privkey, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, message, signature3, &signaturelen3, privkey, NULL, extra) == 1); CHECK(signaturelen3 > 0); extra[31] = 0; extra[0] = 1; - CHECK(secp256k1_ecdsa_sign(message, signature4, &signaturelen4, privkey, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, message, signature4, &signaturelen4, privkey, NULL, extra) == 1); CHECK(signaturelen3 > 0); CHECK((signaturelen != signaturelen2) || (memcmp(signature, signature2, signaturelen) != 0)); CHECK((signaturelen != signaturelen3) || (memcmp(signature, signature3, signaturelen) != 0)); @@ -1320,24 +1506,24 @@ void test_ecdsa_end_to_end(void) { CHECK((signaturelen4 != signaturelen2) || (memcmp(signature4, signature2, signaturelen4) != 0)); CHECK((signaturelen4 != signaturelen) || (memcmp(signature4, signature, signaturelen4) != 0)); /* Verify. */ - CHECK(secp256k1_ecdsa_verify(message, signature, signaturelen, pubkey, pubkeylen) == 1); - CHECK(secp256k1_ecdsa_verify(message, signature2, signaturelen2, pubkey, pubkeylen) == 1); - CHECK(secp256k1_ecdsa_verify(message, signature3, signaturelen3, pubkey, pubkeylen) == 1); - CHECK(secp256k1_ecdsa_verify(message, signature4, signaturelen4, pubkey, pubkeylen) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, message, signature, signaturelen, pubkey, pubkeylen) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, message, signature2, signaturelen2, pubkey, pubkeylen) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, message, signature3, signaturelen3, pubkey, pubkeylen) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, message, signature4, signaturelen4, pubkey, pubkeylen) == 1); /* Destroy signature and verify again. */ signature[signaturelen - 1 - secp256k1_rand32() % 20] += 1 + (secp256k1_rand32() % 255); - CHECK(secp256k1_ecdsa_verify(message, signature, signaturelen, pubkey, pubkeylen) != 1); + CHECK(secp256k1_ecdsa_verify(ctx, message, signature, signaturelen, pubkey, pubkeylen) != 1); /* Compact sign. */ - CHECK(secp256k1_ecdsa_sign_compact(message, csignature, privkey, NULL, NULL, &recid) == 1); + CHECK(secp256k1_ecdsa_sign_compact(ctx, message, csignature, privkey, NULL, NULL, &recid) == 1); CHECK(!is_empty_compact_signature(csignature)); /* Recover. */ - CHECK(secp256k1_ecdsa_recover_compact(message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1); + CHECK(secp256k1_ecdsa_recover_compact(ctx, message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1); CHECK(recpubkeylen == pubkeylen); CHECK(memcmp(pubkey, recpubkey, pubkeylen) == 0); /* Destroy signature and verify again. */ csignature[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255); - CHECK(secp256k1_ecdsa_recover_compact(message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) != 1 || + CHECK(secp256k1_ecdsa_recover_compact(ctx, message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) != 1 || memcmp(pubkey, recpubkey, pubkeylen) != 0); CHECK(recpubkeylen == pubkeylen); @@ -1351,7 +1537,9 @@ void test_random_pubkeys(void) { uint32_t r = secp256k1_rand32(); int len = (r & 3) == 0 ? 65 : 33; r>>=2; - if ((r & 3) == 0) len = (r & 252) >> 3; + if ((r & 3) == 0) { + len = (r & 252) >> 3; + } r>>=8; if (len == 65) { in[0] = (r & 2) ? 4 : (r & 1? 6 : 7); @@ -1359,10 +1547,16 @@ void test_random_pubkeys(void) { in[0] = (r & 1) ? 2 : 3; } r>>=2; - if ((r & 7) == 0) in[0] = (r & 2040) >> 3; + if ((r & 7) == 0) { + in[0] = (r & 2040) >> 3; + } r>>=11; - if (len > 1) secp256k1_rand256(&in[1]); - if (len > 33) secp256k1_rand256(&in[33]); + if (len > 1) { + secp256k1_rand256(&in[1]); + } + if (len > 33) { + secp256k1_rand256(&in[33]); + } if (secp256k1_eckey_pubkey_parse(&elem, in, len)) { unsigned char out[65]; unsigned char firstb; @@ -1374,7 +1568,9 @@ void test_random_pubkeys(void) { CHECK(size == len); CHECK(memcmp(&in[1], &out[1], len-1) == 0); /* ... except for the type of hybrid inputs. */ - if ((in[0] != 6) && (in[0] != 7)) CHECK(in[0] == out[0]); + if ((in[0] != 6) && (in[0] != 7)) { + CHECK(in[0] == out[0]); + } size = 65; CHECK(secp256k1_eckey_pubkey_serialize(&elem, in, &size, 0)); CHECK(size == 65); @@ -1384,8 +1580,11 @@ void test_random_pubkeys(void) { in[0] = (r & 1) ? 6 : 7; res = secp256k1_eckey_pubkey_parse(&elem2, in, size); if (firstb == 2 || firstb == 3) { - if (in[0] == firstb + 4) CHECK(res); - else CHECK(!res); + if (in[0] == firstb + 4) { + CHECK(res); + } else { + CHECK(!res); + } } if (res) { ge_equals_ge(&elem,&elem2); @@ -1447,10 +1646,10 @@ void test_ecdsa_edge_cases(void) { int pubkeyblen = 33; int recid; - CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 0)); - CHECK(secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 1)); - CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 2)); - CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 3)); + CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 0)); + CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 1)); + CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 2)); + CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 3)); for (recid = 0; recid < 4; recid++) { int i; @@ -1495,42 +1694,44 @@ void test_ecdsa_edge_cases(void) { 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04 }; - CHECK(secp256k1_ecdsa_recover_compact(msg32, sigb64, pubkeyb, &pubkeyblen, 1, recid)); - CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 1); + CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigb64, pubkeyb, &pubkeyblen, 1, recid)); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 1); for (recid2 = 0; recid2 < 4; recid2++) { unsigned char pubkey2b[33]; int pubkey2blen = 33; - CHECK(secp256k1_ecdsa_recover_compact(msg32, sigb64, pubkey2b, &pubkey2blen, 1, recid2)); + CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigb64, pubkey2b, &pubkey2blen, 1, recid2)); /* Verifying with (order + r,4) should always fail. */ - CHECK(secp256k1_ecdsa_verify(msg32, sigbderlong, sizeof(sigbderlong), pubkey2b, pubkey2blen) != 1); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderlong, sizeof(sigbderlong), pubkey2b, pubkey2blen) != 1); } /* DER parsing tests. */ /* Zero length r/s. */ - CHECK(secp256k1_ecdsa_verify(msg32, sigcder_zr, sizeof(sigcder_zr), pubkeyb, pubkeyblen) == -2); - CHECK(secp256k1_ecdsa_verify(msg32, sigcder_zs, sizeof(sigcder_zs), pubkeyb, pubkeyblen) == -2); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder_zr, sizeof(sigcder_zr), pubkeyb, pubkeyblen) == -2); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder_zs, sizeof(sigcder_zs), pubkeyb, pubkeyblen) == -2); /* Leading zeros. */ - CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt1, sizeof(sigbderalt1), pubkeyb, pubkeyblen) == 1); - CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt2, sizeof(sigbderalt2), pubkeyb, pubkeyblen) == 1); - CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == 1); - CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt1, sizeof(sigbderalt1), pubkeyb, pubkeyblen) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt2, sizeof(sigbderalt2), pubkeyb, pubkeyblen) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == 1); sigbderalt3[4] = 1; - CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == -2); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == -2); sigbderalt4[7] = 1; - CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == -2); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == -2); /* Damage signature. */ sigbder[7]++; - CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 0); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 0); sigbder[7]--; - CHECK(secp256k1_ecdsa_verify(msg32, sigbder, 6, pubkeyb, pubkeyblen) == -2); - CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder)-1, pubkeyb, pubkeyblen) == -2); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, 6, pubkeyb, pubkeyblen) == -2); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder)-1, pubkeyb, pubkeyblen) == -2); for(i = 0; i < 8; i++) { int c; unsigned char orig = sigbder[i]; /*Try every single-byte change.*/ for (c = 0; c < 256; c++) { - if (c == orig ) continue; + if (c == orig ) { + continue; + } sigbder[i] = c; - CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == (i==4 || i==7) ? 0 : -2 ); } sigbder[i] = orig; @@ -1547,10 +1748,10 @@ void test_ecdsa_edge_cases(void) { secp256k1_scalar_negate(&sig.s, &sig.s); secp256k1_scalar_inverse(&sig.s, &sig.s); secp256k1_scalar_set_int(&sig.r, 1); - secp256k1_ecmult_gen(&keyj, &sig.r); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &keyj, &sig.r); secp256k1_ge_set_gej(&key, &keyj); msg = sig.s; - CHECK(secp256k1_ecdsa_sig_verify(&sig, &key, &msg) == 0); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &key, &msg) == 0); } /* Test r/s equal to zero */ @@ -1569,18 +1770,18 @@ void test_ecdsa_edge_cases(void) { }; unsigned char pubkeyc[65]; int pubkeyclen = 65; - CHECK(secp256k1_ecdsa_recover_compact(msg32, sigc64, pubkeyc, &pubkeyclen, 0, 0) == 1); - CHECK(secp256k1_ecdsa_verify(msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 1); + CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyc, &pubkeyclen, 0, 0) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 1); sigcder[4] = 0; sigc64[31] = 0; - CHECK(secp256k1_ecdsa_recover_compact(msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0); - CHECK(secp256k1_ecdsa_verify(msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0); + CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0); sigcder[4] = 1; sigcder[7] = 0; sigc64[31] = 1; sigc64[63] = 0; - CHECK(secp256k1_ecdsa_recover_compact(msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0); - CHECK(secp256k1_ecdsa_verify(msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0); + CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0); + CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0); } /*Signature where s would be zero.*/ @@ -1611,18 +1812,18 @@ void test_ecdsa_edge_cases(void) { }; unsigned char sig[72]; int siglen = 72; - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 0); + CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 0); CHECK(siglen == 0); - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 0); + CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 0); CHECK(siglen == 0); msg[31] = 0xaa; siglen = 72; - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 1); CHECK(siglen > 0); - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 1); CHECK(siglen > 0); siglen = 10; - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) != 1); + CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) != 1); CHECK(siglen == 0); } @@ -1644,41 +1845,41 @@ void test_ecdsa_edge_cases(void) { msg[31] = 1; /* High key results in signature failure. */ memset(key, 0xFF, 32); - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, NULL, extra) == 0); + CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 0); CHECK(siglen == 0); /* Zero key results in signature failure. */ memset(key, 0, 32); - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, NULL, extra) == 0); + CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 0); CHECK(siglen == 0); /* Nonce function failure results in signature failure. */ key[31] = 1; - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce_function_test_fail, extra) == 0); + CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, nonce_function_test_fail, extra) == 0); CHECK(siglen == 0); - CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, nonce_function_test_fail, extra, &recid) == 0); + CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, nonce_function_test_fail, extra, &recid) == 0); CHECK(is_empty_compact_signature(sig)); /* The retry loop successfully makes its way to the first good value. */ siglen = 72; - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce_function_test_retry, extra) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, nonce_function_test_retry, extra) == 1); CHECK(siglen > 0); - CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, nonce_function_rfc6979, extra) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, nonce_function_rfc6979, extra) == 1); CHECK(siglen > 0); CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0)); - CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, nonce_function_test_retry, extra, &recid) == 1); + CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, nonce_function_test_retry, extra, &recid) == 1); CHECK(!is_empty_compact_signature(sig)); - CHECK(secp256k1_ecdsa_sign_compact(msg, sig2, key, nonce_function_rfc6979, extra, &recid2) == 1); + CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig2, key, nonce_function_rfc6979, extra, &recid2) == 1); CHECK(!is_empty_compact_signature(sig2)); CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0)); /* The default nonce function is determinstic. */ siglen = 72; siglen2 = 72; - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 1); CHECK(siglen > 0); - CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1); CHECK(siglen2 > 0); CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0)); - CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, NULL, extra, &recid) == 1); + CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, NULL, extra, &recid) == 1); CHECK(!is_empty_compact_signature(sig)); - CHECK(secp256k1_ecdsa_sign_compact(msg, sig2, key, NULL, extra, &recid2) == 1); + CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig2, key, NULL, extra, &recid2) == 1); CHECK(!is_empty_compact_signature(sig)); CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0)); /* The default nonce function changes output with different messages. */ @@ -1686,7 +1887,7 @@ void test_ecdsa_edge_cases(void) { int j; siglen2 = 72; msg[0] = i; - CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1); CHECK(!is_empty_compact_signature(sig)); CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2)); for (j = 0; j < i; j++) { @@ -1700,7 +1901,7 @@ void test_ecdsa_edge_cases(void) { int j; siglen2 = 72; key[0] = i - 256; - CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1); CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2)); for (j = 0; j < i; j++) { CHECK(!secp256k1_scalar_eq(&s[i].r, &s[j].r)); @@ -1719,8 +1920,8 @@ void test_ecdsa_edge_cases(void) { 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41, }; int outlen = 300; - CHECK(!secp256k1_ec_privkey_export(seckey, privkey, &outlen, 0)); - CHECK(!secp256k1_ec_privkey_export(seckey, privkey, &outlen, 1)); + CHECK(!secp256k1_ec_privkey_export(ctx, seckey, privkey, &outlen, 0)); + CHECK(!secp256k1_ec_privkey_export(ctx, seckey, privkey, &outlen, 1)); } } @@ -1735,7 +1936,7 @@ EC_KEY *get_openssl_key(const secp256k1_scalar_t *key) { const unsigned char* pbegin = privkey; int compr = secp256k1_rand32() & 1; EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1); - CHECK(secp256k1_eckey_privkey_serialize(privkey, &privkeylen, key, compr)); + CHECK(secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, &privkeylen, key, compr)); CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen)); CHECK(EC_KEY_check_key(ec_key)); return ec_key; @@ -1756,16 +1957,16 @@ void test_ecdsa_openssl(void) { secp256k1_rand256_test(message); secp256k1_scalar_set_b32(&msg, message, NULL); random_scalar_order_test(&key); - secp256k1_ecmult_gen(&qj, &key); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &qj, &key); secp256k1_ge_set_gej(&q, &qj); ec_key = get_openssl_key(&key); CHECK(ec_key); CHECK(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key)); CHECK(secp256k1_ecdsa_sig_parse(&sig, signature, sigsize)); - CHECK(secp256k1_ecdsa_sig_verify(&sig, &q, &msg)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &q, &msg)); secp256k1_scalar_set_int(&one, 1); secp256k1_scalar_add(&msg2, &msg, &one); - CHECK(!secp256k1_ecdsa_sig_verify(&sig, &q, &msg2)); + CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &q, &msg2)); random_sign(&sig, &key, &msg, NULL); CHECK(secp256k1_ecdsa_sig_serialize(signature, &secp_sigsize, &sig)); @@ -1825,10 +2026,13 @@ int main(int argc, char **argv) { printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]); /* initialize */ - secp256k1_start(SECP256K1_START_SIGN | SECP256K1_START_VERIFY); + run_context_tests(); + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - /* initializing a second time shouldn't cause any harm or memory leaks. */ - secp256k1_start(SECP256K1_START_SIGN | SECP256K1_START_VERIFY); + if (secp256k1_rand32() & 1) { + secp256k1_rand256(run32); + CHECK(secp256k1_context_randomize(ctx, secp256k1_rand32() & 1 ? run32 : NULL)); + } run_sha256_tests(); run_hmac_sha256_tests(); @@ -1858,6 +2062,8 @@ int main(int argc, char **argv) { run_wnaf(); run_point_times_order(); run_ecmult_chain(); + run_ecmult_constants(); + run_ecmult_gen_blind(); /* ecdsa tests */ run_random_pubkeys(); @@ -1872,9 +2078,6 @@ int main(int argc, char **argv) { printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]); /* shutdown */ - secp256k1_stop(); - - /* shutting down twice shouldn't cause any double frees. */ - secp256k1_stop(); + secp256k1_context_destroy(ctx); return 0; } diff --git a/src/serialize.h b/src/serialize.h index 741f78f8b4..53d8af142f 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -6,6 +6,8 @@ #ifndef BITCOIN_SERIALIZE_H #define BITCOIN_SERIALIZE_H +#include "compat/endian.h" + #include <algorithm> #include <assert.h> #include <ios> @@ -18,8 +20,6 @@ #include <utility> #include <vector> -#include "compat/endian.h" - class CScript; static const unsigned int MAX_SIZE = 0x02000000; diff --git a/src/support/pagelocker.h b/src/support/pagelocker.h index 3fd793072f..88b95cce73 100644 --- a/src/support/pagelocker.h +++ b/src/support/pagelocker.h @@ -37,7 +37,6 @@ public: ~LockedPageManagerBase() { - assert(this->GetLockedPageCount() == 0); } diff --git a/src/sync.cpp b/src/sync.cpp index a422939964..1837e8d53d 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -33,20 +33,22 @@ void PrintLockContention(const char* pszName, const char* pszFile, int nLine) // struct CLockLocation { - CLockLocation(const char* pszName, const char* pszFile, int nLine) + CLockLocation(const char* pszName, const char* pszFile, int nLine, bool fTryIn) { mutexName = pszName; sourceFile = pszFile; sourceLine = nLine; + fTry = fTryIn; } std::string ToString() const { - return mutexName + " " + sourceFile + ":" + itostr(sourceLine); + return mutexName + " " + sourceFile + ":" + itostr(sourceLine) + (fTry ? " (TRY)" : ""); } std::string MutexName() const { return mutexName; } + bool fTry; private: std::string mutexName; std::string sourceFile; @@ -62,23 +64,52 @@ static boost::thread_specific_ptr<LockStack> lockstack; static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2) { + // We attempt to not assert on probably-not deadlocks by assuming that + // a try lock will immediately have otherwise bailed if it had + // failed to get the lock + // We do this by, for the locks which triggered the potential deadlock, + // in either lockorder, checking that the second of the two which is locked + // is only a TRY_LOCK, ignoring locks if they are reentrant. + bool firstLocked = false; + bool secondLocked = false; + bool onlyMaybeDeadlock = false; + LogPrintf("POTENTIAL DEADLOCK DETECTED\n"); LogPrintf("Previous lock order was:\n"); BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s2) { - if (i.first == mismatch.first) + if (i.first == mismatch.first) { LogPrintf(" (1)"); - if (i.first == mismatch.second) + if (!firstLocked && secondLocked && i.second.fTry) + onlyMaybeDeadlock = true; + firstLocked = true; + } + if (i.first == mismatch.second) { LogPrintf(" (2)"); + if (!secondLocked && firstLocked && i.second.fTry) + onlyMaybeDeadlock = true; + secondLocked = true; + } LogPrintf(" %s\n", i.second.ToString()); } + firstLocked = false; + secondLocked = false; LogPrintf("Current lock order is:\n"); BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s1) { - if (i.first == mismatch.first) + if (i.first == mismatch.first) { LogPrintf(" (1)"); - if (i.first == mismatch.second) + if (!firstLocked && secondLocked && i.second.fTry) + onlyMaybeDeadlock = true; + firstLocked = true; + } + if (i.first == mismatch.second) { LogPrintf(" (2)"); + if (!secondLocked && firstLocked && i.second.fTry) + onlyMaybeDeadlock = true; + secondLocked = true; + } LogPrintf(" %s\n", i.second.ToString()); } + assert(onlyMaybeDeadlock); } static void push_lock(void* c, const CLockLocation& locklocation, bool fTry) @@ -101,10 +132,8 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry) lockorders[p1] = (*lockstack); std::pair<void*, void*> p2 = std::make_pair(c, i.first); - if (lockorders.count(p2)) { + if (lockorders.count(p2)) potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]); - break; - } } } dd_mutex.unlock(); @@ -119,7 +148,7 @@ static void pop_lock() void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry) { - push_lock(cs, CLockLocation(pszName, pszFile, nLine), fTry); + push_lock(cs, CLockLocation(pszName, pszFile, nLine, fTry), fTry); } void LeaveCritical() diff --git a/src/sync.h b/src/sync.h index 78b9043477..68a9443084 100644 --- a/src/sync.h +++ b/src/sync.h @@ -16,7 +16,7 @@ //////////////////////////////////////////////// // // -// THE SIMPLE DEFINITON, EXCLUDING DEBUG CODE // +// THE SIMPLE DEFINITION, EXCLUDING DEBUG CODE // // // //////////////////////////////////////////////// @@ -101,7 +101,7 @@ void PrintLockContention(const char* pszName, const char* pszFile, int nLine); /** Wrapper around boost::unique_lock<Mutex> */ template <typename Mutex> -class CMutexLock +class SCOPED_LOCKABLE CMutexLock { private: boost::unique_lock<Mutex> lock; @@ -129,7 +129,7 @@ private: } public: - CMutexLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) : lock(mutexIn, boost::defer_lock) + CMutexLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : lock(mutexIn, boost::defer_lock) { if (fTry) TryEnter(pszName, pszFile, nLine); @@ -137,7 +137,7 @@ public: Enter(pszName, pszFile, nLine); } - CMutexLock(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) + CMutexLock(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn) { if (!pmutexIn) return; @@ -148,7 +148,7 @@ public: Enter(pszName, pszFile, nLine); } - ~CMutexLock() + ~CMutexLock() UNLOCK_FUNCTION() { if (lock.owns_lock()) LeaveCritical(); diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp index c3125d76dc..0a23c430ed 100644 --- a/src/test/Checkpoints_tests.cpp +++ b/src/test/Checkpoints_tests.cpp @@ -10,6 +10,7 @@ #include "uint256.h" #include "test/test_bitcoin.h" +#include "chainparams.h" #include <boost/test/unit_test.hpp> @@ -19,21 +20,8 @@ BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(sanity) { - uint256 p11111 = uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"); - uint256 p134444 = uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"); - BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111)); - BOOST_CHECK(Checkpoints::CheckBlock(134444, p134444)); - - - // Wrong hashes at checkpoints should fail: - BOOST_CHECK(!Checkpoints::CheckBlock(11111, p134444)); - BOOST_CHECK(!Checkpoints::CheckBlock(134444, p11111)); - - // ... but any hash not at a checkpoint should succeed: - BOOST_CHECK(Checkpoints::CheckBlock(11111+1, p134444)); - BOOST_CHECK(Checkpoints::CheckBlock(134444+1, p11111)); - - BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 134444); -} + const CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints(); + BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate(checkpoints) >= 134444); +} BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index bf25548755..da296a0461 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -2,12 +2,9 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -// // Unit tests for denial-of-service detection/prevention code -// - - +#include "chainparams.h" #include "keystore.h" #include "main.h" #include "net.h" diff --git a/src/test/README.md b/src/test/README.md index 7efce6f052..e36112bd4f 100644 --- a/src/test/README.md +++ b/src/test/README.md @@ -18,4 +18,16 @@ uint256_tests.cpp. For further reading, I found the following website to be helpful in explaining how the boost unit test framework works: -[http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/](http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/).
\ No newline at end of file +[http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/](http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/). + +test_bitcoin has some built-in command-line arguments; for +example, to run just the getarg_tests verbosely: + + test_bitcoin --log_level=all --run_test=getarg_tests + +... or to run just the doubledash test: + + test_bitcoin --run_test=getarg_tests/doubledash + +Run test_bitcoin --help for the full list. + diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index 6b6df5199a..dd3c51d09b 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -2,15 +2,14 @@ // 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 "alert.h" +#include "chain.h" +#include "chainparams.h" #include "clientversion.h" #include "data/alertTests.raw.h" - -#include "chainparams.h" +#include "main.h" // For PartitionCheck #include "serialize.h" #include "streams.h" #include "util.h" @@ -163,8 +162,8 @@ BOOST_AUTO_TEST_CASE(AlertNotify) SetMockTime(11); const std::vector<unsigned char>& alertKey = Params(CBaseChainParams::MAIN).AlertKey(); - boost::filesystem::path temp = GetTempPath() / "alertnotify.txt"; - boost::filesystem::remove(temp); + boost::filesystem::path temp = GetTempPath() / + boost::filesystem::unique_path("alertnotify-%%%%.txt"); mapArgs["-alertnotify"] = std::string("echo %s >> ") + temp.string(); @@ -193,4 +192,63 @@ BOOST_AUTO_TEST_CASE(AlertNotify) 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; + + // 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 + } + + // Test 1: chain with blocks every nPowTargetSpacing seconds, + // as normal, no worries: + PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); + BOOST_CHECK(strMiscWarning.empty()); + + // 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() diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index f07dd7a7db..9e74f5f427 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -17,23 +17,20 @@ #include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" -using namespace json_spirit; -extern Array read_json(const std::string& jsondata); +#include "univalue/univalue.h" + +extern UniValue read_json(const std::string& jsondata); BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup) // Goal: test low-level base58 encoding functionality BOOST_AUTO_TEST_CASE(base58_EncodeBase58) { - Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + UniValue tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + UniValue test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 2) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); @@ -50,13 +47,12 @@ BOOST_AUTO_TEST_CASE(base58_EncodeBase58) // Goal: test low-level base58 decoding functionality BOOST_AUTO_TEST_CASE(base58_DecodeBase58) { - Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); + UniValue tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); std::vector<unsigned char> result; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + UniValue test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 2) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); @@ -124,16 +120,15 @@ public: // Goal: check that parsed keys match test payload BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) { - Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); + UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); std::vector<unsigned char> result; CBitcoinSecret secret; CBitcoinAddress addr; SelectParams(CBaseChainParams::MAIN); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + UniValue test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 3) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); @@ -141,7 +136,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) } std::string exp_base58string = test[0].get_str(); std::vector<unsigned char> exp_payload = ParseHex(test[1].get_str()); - const Object &metadata = test[2].get_obj(); + const UniValue &metadata = test[2].get_obj(); bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); bool isTestnet = find_value(metadata, "isTestnet").get_bool(); if (isTestnet) @@ -183,12 +178,12 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) // Goal: check that generated keys match test vectors BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) { - Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); + UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); std::vector<unsigned char> result; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + + for (unsigned int idx = 0; idx < tests.size(); idx++) { + UniValue test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 3) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); @@ -196,7 +191,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) } std::string exp_base58string = test[0].get_str(); std::vector<unsigned char> exp_payload = ParseHex(test[1].get_str()); - const Object &metadata = test[2].get_obj(); + const UniValue &metadata = test[2].get_obj(); bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); bool isTestnet = find_value(metadata, "isTestnet").get_bool(); if (isTestnet) @@ -251,15 +246,14 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) // Goal: check that base58 parsing code is robust against a variety of corrupted data BOOST_AUTO_TEST_CASE(base58_keys_invalid) { - Array tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); // Negative testcases + UniValue tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); // Negative testcases std::vector<unsigned char> result; CBitcoinSecret secret; CBitcoinAddress addr; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + UniValue test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 1) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 0d815c27fd..69084213a2 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -88,12 +88,23 @@ void RunTest(const TestVector &test) { unsigned char data[74]; key.Encode(data); pubkey.Encode(data); + // Test private key CBitcoinExtKey b58key; b58key.SetKey(key); BOOST_CHECK(b58key.ToString() == derive.prv); + + CBitcoinExtKey b58keyDecodeCheck(derive.prv); + CExtKey checkKey = b58keyDecodeCheck.GetKey(); + assert(checkKey == key); //ensure a base58 decoded key also matches + // Test public key CBitcoinExtPubKey b58pubkey; b58pubkey.SetKey(pubkey); BOOST_CHECK(b58pubkey.ToString() == derive.pub); + + CBitcoinExtPubKey b58PubkeyDecodeCheck(derive.pub); + CExtPubKey checkPubKey = b58PubkeyDecodeCheck.GetKey(); + assert(checkPubKey == pubkey); //ensure a base58 decoded pubkey also matches + // Derive new keys CExtKey keyNew; BOOST_CHECK(key.Derive(keyNew, derive.nChild)); diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 1bda8a7ea1..6b30d6aa8a 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -469,7 +469,7 @@ static std::vector<unsigned char> RandomData() BOOST_AUTO_TEST_CASE(rolling_bloom) { // last-100-entry, 1% false positive: - CRollingBloomFilter rb1(100, 0.01, 0); + CRollingBloomFilter rb1(100, 0.01); // Overfill: static const int DATASIZE=399; @@ -500,7 +500,7 @@ BOOST_AUTO_TEST_CASE(rolling_bloom) BOOST_CHECK(nHits < 175); BOOST_CHECK(rb1.contains(data[DATASIZE-1])); - rb1.clear(); + rb1.reset(); BOOST_CHECK(!rb1.contains(data[DATASIZE-1])); // Now roll through data, make sure last 100 entries @@ -527,7 +527,7 @@ BOOST_AUTO_TEST_CASE(rolling_bloom) BOOST_CHECK(nHits < 100); // last-1000-entry, 0.01% false positive: - CRollingBloomFilter rb2(1000, 0.001, 0); + CRollingBloomFilter rb2(1000, 0.001); for (int i = 0; i < DATASIZE; i++) { rb2.insert(data[i]); } diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp index 7abfad151e..f7e2470617 100644 --- a/src/test/checkblock_tests.cpp +++ b/src/test/checkblock_tests.cpp @@ -2,16 +2,12 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -// -// Unit tests for block.CheckBlock() -// - - - #include "clientversion.h" -#include "main.h" -#include "utiltime.h" +#include "consensus/validation.h" +#include "main.h" // For CheckBlock +#include "primitives/block.h" #include "test/test_bitcoin.h" +#include "utiltime.h" #include <cstdio> diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 2e2cc2214b..13d848311a 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -59,6 +59,24 @@ public: bool GetStats(CCoinsStats& stats) const { return false; } }; + +class CCoinsViewCacheTest : public CCoinsViewCache +{ +public: + CCoinsViewCacheTest(CCoinsView* base) : CCoinsViewCache(base) {} + + void SelfTest() const + { + // Manually recompute the dynamic usage of the whole data, and compare it. + size_t ret = memusage::DynamicUsage(cacheCoins); + for (CCoinsMap::iterator it = cacheCoins.begin(); it != cacheCoins.end(); it++) { + ret += it->second.coins.DynamicMemoryUsage(); + } + BOOST_CHECK_EQUAL(DynamicMemoryUsage(), ret); + } + +}; + } BOOST_FIXTURE_TEST_SUITE(coins_tests, BasicTestingSetup) @@ -90,8 +108,8 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test) // The cache stack. CCoinsViewTest base; // A CCoinsViewTest at the bottom. - std::vector<CCoinsViewCache*> stack; // A stack of CCoinsViewCaches on top. - stack.push_back(new CCoinsViewCache(&base)); // Start with one cache. + std::vector<CCoinsViewCacheTest*> stack; // A stack of CCoinsViewCaches on top. + stack.push_back(new CCoinsViewCacheTest(&base)); // Start with one cache. // Use a limited set of random transaction ids, so we do test overwriting entries. std::vector<uint256> txids; @@ -136,6 +154,9 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test) missed_an_entry = true; } } + BOOST_FOREACH(const CCoinsViewCacheTest *test, stack) { + test->SelfTest(); + } } if (insecure_rand() % 100 == 0) { @@ -152,7 +173,7 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test) } else { removed_all_caches = true; } - stack.push_back(new CCoinsViewCache(tip)); + stack.push_back(new CCoinsViewCacheTest(tip)); if (stack.size() == 4) { reached_4_caches = true; } diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json index 6090421cb6..3bf80ca434 100644 --- a/src/test/data/bitcoin-util-test.json +++ b/src/test/data/bitcoin-util-test.json @@ -52,9 +52,39 @@ ["-create", "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0", "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]", - "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\"}]", + "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]", "sign=ALL", "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"], "output_cmp": "txcreatesign.hex" + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", + "outdata=4:badhexdata"], + "return_code": 1 + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", + "outdata=badhexdata"], + "return_code": 1 + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", + "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o", + "outdata=4:54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"], + "output_cmp": "txcreatedata1.hex" + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", + "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o", + "outdata=54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"], + "output_cmp": "txcreatedata2.hex" } ] diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index 064dde8464..a4e15faeaf 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -74,12 +74,14 @@ ["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"], ["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"], ["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"], @@ -408,6 +410,7 @@ ["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", "1ADD", "P2SH,STRICTENC"], ["2", "1SUB", "P2SH,STRICTENC"], diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 456e0d2f7b..5cad5af7c3 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -19,6 +19,12 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1 0x4c 0x47 0x3044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a01"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000006b4c473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", "P2SH"], +["This is the nearly-standard transaction with CHECKSIGVERIFY 1 instead of CHECKSIG from tx_valid.json"], +["but with the signature duplicated in the scriptPubKey with a different hashtype suffix"], +["See FindAndDelete, which will only remove if the signature, including the hash type, matches"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1 0x47 0x3044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a81"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006a473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", "P2SH"], + ["An invalid P2SH Transaction"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", "P2SH"], @@ -114,6 +120,78 @@ [[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]], "010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a483045022100fa4a74ba9fd59c59f46c3960cf90cbe0d2b743c471d24a3d5d6db6002af5eebb02204d70ec490fd0f7055a7c45f86514336e3a7f03503dacecabb247fc23f15c83510100ffffffff010000000000000000016a00000000", "P2SH"], +["CHECKLOCKTIMEVERIFY tests"], + +["By-height locks, with argument just beyond tx nLockTime"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 NOP2 1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], +"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000fe64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], + +["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 NOP2 1"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]], +"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"], + +["Argument missing"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "NOP2 1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000001b1010000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], + +["Argument negative with by-blockheight nLockTime=0"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], + +["Argument negative with by-blocktime nLockTime=500,000,000"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000004005194b1010000000100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"], + +["Input locked"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 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"] , + ["0000000000000000000000000000000000000000000000000000000000000200", 1, "1"]], +"010000000200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00020000000000000000000000000000000000000000000000000000000000000100000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], + +["Argument/tx height/time mismatch, both versions"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b100000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], + +["Argument 2^32 with nLockTime=2^32-1"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967296 NOP2 1"]], +"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"], + +["Same, but with nLockTime=2^31-1"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP2 1"]], +"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffff7f", "P2SH,CHECKLOCKTIMEVERIFY"], + +["6 byte non-minimally-encoded arguments are invalid even if their contents are valid"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 NOP2 1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], + +["Failure due to failing CHECKLOCKTIMEVERIFY in scriptSig"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b1000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], + +["Failure due to failing CHECKLOCKTIMEVERIFY in redeemScript"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xc5b93064159b3b2d6ab506a41b1f50463771b988 EQUAL"]], +"0100000001000100000000000000000000000000000000000000000000000000000000000000000000030251b1000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["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 182b88ef67..9744a3c848 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -187,5 +187,47 @@ "0100000002dbb33bdf185b17f758af243c5d3c6e164cc873f6bb9f40c0677d6e0f8ee5afce000000006b4830450221009627444320dc5ef8d7f68f35010b4c050a6ed0d96b67a84db99fda9c9de58b1e02203e4b4aaa019e012e65d69b487fdf8719df72f488fa91506a80c49a33929f1fd50121022b78b756e2258af13779c1a1f37ea6800259716ca4b7f0b87610e0bf3ab52a01ffffffffdbb33bdf185b17f758af243c5d3c6e164cc873f6bb9f40c0677d6e0f8ee5afce010000009300483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303ffffffff01a0860100000000001976a9149bc0bbdd3024da4d0c38ed1aecf5c68dd1d3fa1288ac00000000", "P2SH"], +["CHECKLOCKTIMEVERIFY tests"], + +["By-height locks, with argument == 0 and == tx nLockTime"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], +"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], + +["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]], +"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"], + +["Any non-maxint nSequence is fine"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], + +["The argument can be calculated rather than created directly by a PUSHDATA"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 1ADD NOP2 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"]], +"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"], + +["5 byte non-minimally-encoded arguments are valid"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 NOP2 1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], + +["Valid CHECKLOCKTIMEVERIFY in scriptSig"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b1000000000100000000000000000001000000", "P2SH,CHECKLOCKTIMEVERIFY"], + +["Valid CHECKLOCKTIMEVERIFY in redeemScript"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xc5b93064159b3b2d6ab506a41b1f50463771b988 EQUAL"]], +"0100000001000100000000000000000000000000000000000000000000000000000000000000000000030251b1000000000100000000000000000001000000", "P2SH,CHECKLOCKTIMEVERIFY"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/data/txcreatedata1.hex b/src/test/data/txcreatedata1.hex new file mode 100644 index 0000000000..eccc7604e6 --- /dev/null +++ b/src/test/data/txcreatedata1.hex @@ -0,0 +1 @@ +01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d71700000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000 diff --git a/src/test/data/txcreatedata2.hex b/src/test/data/txcreatedata2.hex new file mode 100644 index 0000000000..3c7644c297 --- /dev/null +++ b/src/test/data/txcreatedata2.hex @@ -0,0 +1 @@ +01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0000000000000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000 diff --git a/src/test/data/txcreatesign.hex b/src/test/data/txcreatesign.hex index 56ce28a865..a46fcc88cb 100644 --- a/src/test/data/txcreatesign.hex +++ b/src/test/data/txcreatesign.hex @@ -1 +1 @@ -01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d0000000000ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000 +01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d000000008b48304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e201410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000 diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index a0c5592a95..eb61a2884d 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -60,18 +60,18 @@ BOOST_AUTO_TEST_CASE(boolarg) BOOST_CHECK(!GetBoolArg("-foo", false)); BOOST_CHECK(!GetBoolArg("-foo", true)); - ResetArgs("-foo -nofoo"); // -foo should win - BOOST_CHECK(GetBoolArg("-foo", false)); - BOOST_CHECK(GetBoolArg("-foo", true)); - - ResetArgs("-foo=1 -nofoo=1"); // -foo should win - BOOST_CHECK(GetBoolArg("-foo", false)); - BOOST_CHECK(GetBoolArg("-foo", true)); + ResetArgs("-foo -nofoo"); // -nofoo should win + BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!GetBoolArg("-foo", true)); - ResetArgs("-foo=0 -nofoo=0"); // -foo should win + ResetArgs("-foo=1 -nofoo=1"); // -nofoo should win BOOST_CHECK(!GetBoolArg("-foo", false)); BOOST_CHECK(!GetBoolArg("-foo", true)); + ResetArgs("-foo=0 -nofoo=0"); // -nofoo=0 should win + BOOST_CHECK(GetBoolArg("-foo", false)); + BOOST_CHECK(GetBoolArg("-foo", true)); + // New 0.6 feature: treat -- same as -: ResetArgs("--foo=1"); BOOST_CHECK(GetBoolArg("-foo", false)); @@ -150,9 +150,9 @@ BOOST_AUTO_TEST_CASE(boolargno) BOOST_CHECK(GetBoolArg("-foo", true)); BOOST_CHECK(GetBoolArg("-foo", false)); - ResetArgs("-foo --nofoo"); - BOOST_CHECK(GetBoolArg("-foo", true)); - BOOST_CHECK(GetBoolArg("-foo", false)); + ResetArgs("-foo --nofoo"); // --nofoo should win + BOOST_CHECK(!GetBoolArg("-foo", true)); + BOOST_CHECK(!GetBoolArg("-foo", false)); ResetArgs("-nofoo -foo"); // foo always wins: BOOST_CHECK(GetBoolArg("-foo", true)); diff --git a/src/test/limitedmap_tests.cpp b/src/test/limitedmap_tests.cpp new file mode 100644 index 0000000000..faaddffad8 --- /dev/null +++ b/src/test/limitedmap_tests.cpp @@ -0,0 +1,101 @@ +// 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 "limitedmap.h" + +#include "test/test_bitcoin.h" + +#include <boost/test/unit_test.hpp> + +BOOST_FIXTURE_TEST_SUITE(limitedmap_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(limitedmap_test) +{ + // create a limitedmap capped at 10 items + limitedmap<int, int> map(10); + + // check that the max size is 10 + BOOST_CHECK(map.max_size() == 10); + + // check that it's empty + BOOST_CHECK(map.size() == 0); + + // insert (-1, -1) + map.insert(std::pair<int, int>(-1, -1)); + + // make sure that the size is updated + BOOST_CHECK(map.size() == 1); + + // make sure that the new items is in the map + BOOST_CHECK(map.count(-1) == 1); + + // insert 10 new items + for (int i = 0; i < 10; i++) { + map.insert(std::pair<int, int>(i, i + 1)); + } + + // make sure that the map now contains 10 items... + BOOST_CHECK(map.size() == 10); + + // ...and that the first item has been discarded + BOOST_CHECK(map.count(-1) == 0); + + // iterate over the map, both with an index and an iterator + limitedmap<int, int>::const_iterator it = map.begin(); + for (int i = 0; i < 10; i++) { + // make sure the item is present + BOOST_CHECK(map.count(i) == 1); + + // use the iterator to check for the expected key adn value + BOOST_CHECK(it->first == i); + BOOST_CHECK(it->second == i + 1); + + // use find to check for the value + BOOST_CHECK(map.find(i)->second == i + 1); + + // update and recheck + map.update(it, i + 2); + BOOST_CHECK(map.find(i)->second == i + 2); + + it++; + } + + // check that we've exhausted the iterator + BOOST_CHECK(it == map.end()); + + // resize the map to 5 items + map.max_size(5); + + // check that the max size and size are now 5 + BOOST_CHECK(map.max_size() == 5); + BOOST_CHECK(map.size() == 5); + + // check that items less than 5 have been discarded + // and items greater than 5 are retained + for (int i = 0; i < 10; i++) { + if (i < 5) { + BOOST_CHECK(map.count(i) == 0); + } else { + BOOST_CHECK(map.count(i) == 1); + } + } + + // erase some items not in the map + for (int i = 100; i < 1000; i += 100) { + map.erase(i); + } + + // check that the size is unaffected + BOOST_CHECK(map.size() == 5); + + // erase the remaining elements + for (int i = 5; i < 10; i++) { + map.erase(i); + } + + // check that the map is now empty + BOOST_CHECK(map.empty()); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index 9ec533bcca..21ae46d6e9 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -2,25 +2,58 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "primitives/transaction.h" +#include "chainparams.h" #include "main.h" #include "test/test_bitcoin.h" +#include <boost/signals2/signal.hpp> #include <boost/test/unit_test.hpp> BOOST_FIXTURE_TEST_SUITE(main_tests, TestingSetup) +static void TestBlockSubsidyHalvings(const Consensus::Params& consensusParams) +{ + int maxHalvings = 64; + CAmount nInitialSubsidy = 50 * COIN; + + CAmount nPreviousSubsidy = nInitialSubsidy * 2; // for height == 0 + BOOST_CHECK_EQUAL(nPreviousSubsidy, nInitialSubsidy * 2); + for (int nHalvings = 0; nHalvings < maxHalvings; nHalvings++) { + int nHeight = nHalvings * consensusParams.nSubsidyHalvingInterval; + CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams); + BOOST_CHECK(nSubsidy <= nInitialSubsidy); + BOOST_CHECK_EQUAL(nSubsidy, nPreviousSubsidy / 2); + nPreviousSubsidy = nSubsidy; + } + BOOST_CHECK_EQUAL(GetBlockSubsidy(maxHalvings * consensusParams.nSubsidyHalvingInterval, consensusParams), 0); +} + +static void TestBlockSubsidyHalvings(int nSubsidyHalvingInterval) +{ + Consensus::Params consensusParams; + consensusParams.nSubsidyHalvingInterval = nSubsidyHalvingInterval; + TestBlockSubsidyHalvings(consensusParams); +} + +BOOST_AUTO_TEST_CASE(block_subsidy_test) +{ + TestBlockSubsidyHalvings(Params(CBaseChainParams::MAIN).GetConsensus()); // As in main + TestBlockSubsidyHalvings(150); // As in regtest + TestBlockSubsidyHalvings(1000); // Just another interval +} + BOOST_AUTO_TEST_CASE(subsidy_limit_test) { + const Consensus::Params& consensusParams = Params(CBaseChainParams::MAIN).GetConsensus(); CAmount nSum = 0; for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) { - CAmount nSubsidy = GetBlockValue(nHeight, 0); + CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams); BOOST_CHECK(nSubsidy <= 50 * COIN); nSum += nSubsidy * 1000; BOOST_CHECK(MoneyRange(nSum)); } - BOOST_CHECK(nSum == 2099999997690000ULL); + BOOST_CHECK_EQUAL(nSum, 2099999997690000ULL); } bool ReturnFalse() { return false; } diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index 0996e13c48..5bf1e98e8f 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -2,7 +2,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "main.h" #include "txmempool.h" #include "util.h" @@ -10,6 +9,7 @@ #include <boost/test/unit_test.hpp> #include <list> +#include <vector> BOOST_FIXTURE_TEST_SUITE(mempool_tests, TestingSetup) @@ -101,4 +101,184 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) removed.clear(); } +void CheckSort(CTxMemPool &pool, std::vector<std::string> &sortedOrder) +{ + BOOST_CHECK_EQUAL(pool.size(), sortedOrder.size()); + CTxMemPool::indexed_transaction_set::nth_index<1>::type::iterator it = pool.mapTx.get<1>().begin(); + int count=0; + for (; it != pool.mapTx.get<1>().end(); ++it, ++count) { + BOOST_CHECK_EQUAL(it->GetTx().GetHash().ToString(), sortedOrder[count]); + } +} + +BOOST_AUTO_TEST_CASE(MempoolIndexingTest) +{ + CTxMemPool pool(CFeeRate(0)); + + /* 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(), CTxMemPoolEntry(tx1, 10000LL, 0, 10.0, 1, true)); + + /* 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(), CTxMemPoolEntry(tx2, 20000LL, 0, 9.0, 1, true)); + + /* 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(), CTxMemPoolEntry(tx3, 0LL, 0, 100.0, 1, true)); + + /* 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(), CTxMemPoolEntry(tx4, 15000LL, 0, 1.0, 1, true)); + + /* 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(), CTxMemPoolEntry(tx5, 10000LL, 1, 10.0, 1, true)); + BOOST_CHECK_EQUAL(pool.size(), 5); + + std::vector<std::string> sortedOrder; + sortedOrder.resize(5); + sortedOrder[0] = tx2.GetHash().ToString(); // 20000 + sortedOrder[1] = tx4.GetHash().ToString(); // 15000 + sortedOrder[2] = tx1.GetHash().ToString(); // 10000 + sortedOrder[3] = tx5.GetHash().ToString(); // 10000 + sortedOrder[4] = tx3.GetHash().ToString(); // 0 + CheckSort(pool, sortedOrder); + + /* low fee but with high fee child */ + /* tx6 -> tx7 -> tx8, tx9 -> tx10 */ + CMutableTransaction tx6 = CMutableTransaction(); + tx6.vout.resize(1); + tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx6.vout[0].nValue = 20 * COIN; + pool.addUnchecked(tx6.GetHash(), CTxMemPoolEntry(tx6, 0LL, 1, 10.0, 1, true)); + BOOST_CHECK_EQUAL(pool.size(), 6); + // Check that at this point, tx6 is sorted low + sortedOrder.push_back(tx6.GetHash().ToString()); + CheckSort(pool, sortedOrder); + + CTxMemPool::setEntries setAncestors; + setAncestors.insert(pool.mapTx.find(tx6.GetHash())); + 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(2); + tx7.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx7.vout[0].nValue = 10 * COIN; + tx7.vout[1].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx7.vout[1].nValue = 1 * COIN; + + CTxMemPool::setEntries setAncestorsCalculated; + std::string dummy; + CTxMemPoolEntry entry7(tx7, 2000000LL, 1, 10.0, 1, true); + BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry7, setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy), true); + BOOST_CHECK(setAncestorsCalculated == setAncestors); + + pool.addUnchecked(tx7.GetHash(), CTxMemPoolEntry(tx7, 2000000LL, 1, 10.0, 1, true), setAncestors); + BOOST_CHECK_EQUAL(pool.size(), 7); + + // Now tx6 should be sorted higher (high fee child): tx7, tx6, tx2, ... + sortedOrder.erase(sortedOrder.end()-1); + sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString()); + sortedOrder.insert(sortedOrder.begin(), tx7.GetHash().ToString()); + CheckSort(pool, sortedOrder); + + /* low fee child of tx7 */ + CMutableTransaction tx8 = CMutableTransaction(); + tx8.vin.resize(1); + tx8.vin[0].prevout = COutPoint(tx7.GetHash(), 0); + tx8.vin[0].scriptSig = CScript() << OP_11; + tx8.vout.resize(1); + tx8.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx8.vout[0].nValue = 10 * COIN; + setAncestors.insert(pool.mapTx.find(tx7.GetHash())); + pool.addUnchecked(tx8.GetHash(), CTxMemPoolEntry(tx8, 0LL, 2, 10.0, 1, true), setAncestors); + + // Now tx8 should be sorted low, but tx6/tx both high + sortedOrder.push_back(tx8.GetHash().ToString()); + CheckSort(pool, sortedOrder); + + /* low fee child of tx7 */ + CMutableTransaction tx9 = CMutableTransaction(); + tx9.vin.resize(1); + tx9.vin[0].prevout = COutPoint(tx7.GetHash(), 1); + tx9.vin[0].scriptSig = CScript() << OP_11; + tx9.vout.resize(1); + tx9.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx9.vout[0].nValue = 1 * COIN; + pool.addUnchecked(tx9.GetHash(), CTxMemPoolEntry(tx9, 0LL, 3, 10.0, 1, true), setAncestors); + + // tx9 should be sorted low + BOOST_CHECK_EQUAL(pool.size(), 9); + sortedOrder.push_back(tx9.GetHash().ToString()); + CheckSort(pool, sortedOrder); + + std::vector<std::string> snapshotOrder = sortedOrder; + + setAncestors.insert(pool.mapTx.find(tx8.GetHash())); + setAncestors.insert(pool.mapTx.find(tx9.GetHash())); + /* tx10 depends on tx8 and tx9 and has a high fee*/ + CMutableTransaction tx10 = CMutableTransaction(); + tx10.vin.resize(2); + tx10.vin[0].prevout = COutPoint(tx8.GetHash(), 0); + tx10.vin[0].scriptSig = CScript() << OP_11; + tx10.vin[1].prevout = COutPoint(tx9.GetHash(), 0); + tx10.vin[1].scriptSig = CScript() << OP_11; + tx10.vout.resize(1); + tx10.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx10.vout[0].nValue = 10 * COIN; + + setAncestorsCalculated.clear(); + CTxMemPoolEntry entry10(tx10, 200000LL, 4, 10.0, 1, true); + BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry10, setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy), true); + BOOST_CHECK(setAncestorsCalculated == setAncestors); + + pool.addUnchecked(tx10.GetHash(), CTxMemPoolEntry(tx10, 200000LL, 4, 10.0, 1, true), setAncestors); + + /** + * tx8 and tx9 should both now be sorted higher + * Final order after tx10 is added: + * + * tx7 = 2.2M (4 txs) + * tx6 = 2.2M (5 txs) + * tx10 = 200k (1 tx) + * tx8 = 200k (2 txs) + * tx9 = 200k (2 txs) + * tx2 = 20000 (1) + * tx4 = 15000 (1) + * tx1 = 10000 (1) + * tx5 = 10000 (1) + * tx3 = 0 (1) + */ + sortedOrder.erase(sortedOrder.end()-2, sortedOrder.end()); // take out tx8, tx9 from the end + sortedOrder.insert(sortedOrder.begin()+2, tx10.GetHash().ToString()); // tx10 is after tx6 + sortedOrder.insert(sortedOrder.begin()+3, tx9.GetHash().ToString()); + sortedOrder.insert(sortedOrder.begin()+3, tx8.GetHash().ToString()); + CheckSort(pool, sortedOrder); + + // there should be 10 transactions in the mempool + BOOST_CHECK_EQUAL(pool.size(), 10); + + // Now try removing tx10 and verify the sort order returns to normal + std::list<CTransaction> removed; + pool.remove(pool.mapTx.find(tx10.GetHash())->GetTx(), removed, true); + CheckSort(pool, snapshotOrder); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 6ab9cb8a44..91a3a5738e 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -2,11 +2,17 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "chainparams.h" +#include "coins.h" +#include "consensus/validation.h" #include "main.h" #include "miner.h" #include "pubkey.h" +#include "script/standard.h" +#include "txmempool.h" #include "uint256.h" #include "util.h" +#include "utilstrencodings.h" #include "test/test_bitcoin.h" @@ -59,7 +65,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) uint256 hash; LOCK(cs_main); - Checkpoints::fEnabled = false; + fCheckpointsEnabled = false; // Simple block creation, nothing special yet: BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); @@ -73,6 +79,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) pblock->nVersion = 1; pblock->nTime = chainActive.Tip()->GetMedianTimePast()+1; CMutableTransaction txCoinbase(pblock->vtx[0]); + txCoinbase.nVersion = 1; txCoinbase.vin[0].scriptSig = CScript(); txCoinbase.vin[0].scriptSig.push_back(blockinfo[i].extranonce); txCoinbase.vin[0].scriptSig.push_back(chainActive.Height()); @@ -80,10 +87,10 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) pblock->vtx[0] = CTransaction(txCoinbase); if (txFirst.size() < 2) txFirst.push_back(new CTransaction(pblock->vtx[0])); - pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + pblock->hashMerkleRoot = pblock->ComputeMerkleRoot(); pblock->nNonce = blockinfo[i].nonce; CValidationState state; - BOOST_CHECK(ProcessNewBlock(state, NULL, pblock)); + BOOST_CHECK(ProcessNewBlock(state, NULL, pblock, true, NULL)); BOOST_CHECK(state.IsValid()); pblock->hashPrevBlock = pblock->GetHash(); } @@ -222,7 +229,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.nLockTime = chainActive.Tip()->nHeight+1; hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(!IsFinalTx(tx, chainActive.Tip()->nHeight + 1)); + BOOST_CHECK(!CheckFinalTx(tx)); // time locked tx2.vin.resize(1); @@ -236,7 +243,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx2.nLockTime = chainActive.Tip()->GetMedianTimePast()+1; hash = tx2.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(!IsFinalTx(tx2)); + BOOST_CHECK(!CheckFinalTx(tx2)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); @@ -248,8 +255,10 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) chainActive.Tip()->nHeight++; SetMockTime(chainActive.Tip()->GetMedianTimePast()+2); - BOOST_CHECK(IsFinalTx(tx, chainActive.Tip()->nHeight + 1)); - BOOST_CHECK(IsFinalTx(tx2)); + // 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)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3); @@ -262,7 +271,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) BOOST_FOREACH(CTransaction *tx, txFirst) delete tx; - Checkpoints::fEnabled = true; + fCheckpointsEnabled = true; } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 6b189a6b55..b65c299adc 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -4,7 +4,7 @@ #include "key.h" #include "keystore.h" -#include "main.h" +#include "policy/policy.h" #include "script/script.h" #include "script/script_error.h" #include "script/interpreter.h" diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index cb357d295c..b1ef0ed24a 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -7,6 +7,7 @@ #include <string> +#include <boost/assign/list_of.hpp> #include <boost/test/unit_test.hpp> using namespace std; @@ -117,6 +118,11 @@ BOOST_AUTO_TEST_CASE(subnet_test) BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:8").Match(CNetAddr("1:2:3:4:5:6:7:8"))); BOOST_CHECK(!CSubNet("1:2:3:4:5:6:7:8").Match(CNetAddr("1:2:3:4:5:6:7:9"))); BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:0/112").Match(CNetAddr("1:2:3:4:5:6:7:1234"))); + BOOST_CHECK(CSubNet("192.168.0.1/24").Match(CNetAddr("192.168.0.2"))); + BOOST_CHECK(CSubNet("192.168.0.20/29").Match(CNetAddr("192.168.0.18"))); + BOOST_CHECK(CSubNet("1.2.2.1/24").Match(CNetAddr("1.2.2.4"))); + BOOST_CHECK(CSubNet("1.2.2.110/31").Match(CNetAddr("1.2.2.111"))); + BOOST_CHECK(CSubNet("1.2.2.20/26").Match(CNetAddr("1.2.2.63"))); // All-Matching IPv6 Matches arbitrary IPv4 and IPv6 BOOST_CHECK(CSubNet("::/0").Match(CNetAddr("1:2:3:4:5:6:7:1234"))); BOOST_CHECK(CSubNet("::/0").Match(CNetAddr("1.2.3.4"))); @@ -138,6 +144,111 @@ BOOST_AUTO_TEST_CASE(subnet_test) BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:8/128").IsValid()); BOOST_CHECK(!CSubNet("1:2:3:4:5:6:7:8/129").IsValid()); BOOST_CHECK(!CSubNet("fuzzy").IsValid()); + + //CNetAddr constructor test + BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).IsValid()); + BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).Match(CNetAddr("127.0.0.1"))); + BOOST_CHECK(!CSubNet(CNetAddr("127.0.0.1")).Match(CNetAddr("127.0.0.2"))); + BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).ToString() == "127.0.0.1/32"); + + BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).IsValid()); + BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).Match(CNetAddr("1:2:3:4:5:6:7:8"))); + BOOST_CHECK(!CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).Match(CNetAddr("1:2:3:4:5:6:7:9"))); + BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).ToString() == "1:2:3:4:5:6:7:8/128"); + + CSubNet subnet = CSubNet("1.2.3.4/255.255.255.255"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32"); + subnet = CSubNet("1.2.3.4/255.255.255.254"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/31"); + subnet = CSubNet("1.2.3.4/255.255.255.252"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/30"); + subnet = CSubNet("1.2.3.4/255.255.255.248"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/29"); + subnet = CSubNet("1.2.3.4/255.255.255.240"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/28"); + subnet = CSubNet("1.2.3.4/255.255.255.224"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/27"); + subnet = CSubNet("1.2.3.4/255.255.255.192"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/26"); + subnet = CSubNet("1.2.3.4/255.255.255.128"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/25"); + subnet = CSubNet("1.2.3.4/255.255.255.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/24"); + subnet = CSubNet("1.2.3.4/255.255.254.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.2.0/23"); + subnet = CSubNet("1.2.3.4/255.255.252.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/22"); + subnet = CSubNet("1.2.3.4/255.255.248.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/21"); + subnet = CSubNet("1.2.3.4/255.255.240.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/20"); + subnet = CSubNet("1.2.3.4/255.255.224.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/19"); + subnet = CSubNet("1.2.3.4/255.255.192.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/18"); + subnet = CSubNet("1.2.3.4/255.255.128.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/17"); + subnet = CSubNet("1.2.3.4/255.255.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/16"); + subnet = CSubNet("1.2.3.4/255.254.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/15"); + subnet = CSubNet("1.2.3.4/255.252.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/14"); + subnet = CSubNet("1.2.3.4/255.248.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/13"); + subnet = CSubNet("1.2.3.4/255.240.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/12"); + subnet = CSubNet("1.2.3.4/255.224.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/11"); + subnet = CSubNet("1.2.3.4/255.192.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/10"); + subnet = CSubNet("1.2.3.4/255.128.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/9"); + subnet = CSubNet("1.2.3.4/255.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8"); + subnet = CSubNet("1.2.3.4/254.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/7"); + subnet = CSubNet("1.2.3.4/252.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/6"); + subnet = CSubNet("1.2.3.4/248.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/5"); + subnet = CSubNet("1.2.3.4/240.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/4"); + subnet = CSubNet("1.2.3.4/224.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/3"); + subnet = CSubNet("1.2.3.4/192.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/2"); + subnet = CSubNet("1.2.3.4/128.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/1"); + subnet = CSubNet("1.2.3.4/0.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/0"); + + subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1:2:3:4:5:6:7:8/128"); + subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:0000:0000:0000:0000:0000:0000:0000"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1::/16"); + subnet = CSubNet("1:2:3:4:5:6:7:8/0000:0000:0000:0000:0000:0000:0000:0000"); + BOOST_CHECK_EQUAL(subnet.ToString(), "::/0"); + subnet = CSubNet("1.2.3.4/255.255.232.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/255.255.232.0"); + subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f"); +} + +BOOST_AUTO_TEST_CASE(netbase_getgroup) +{ + BOOST_CHECK(CNetAddr("127.0.0.1").GetGroup() == boost::assign::list_of(0)); // Local -> !Routable() + BOOST_CHECK(CNetAddr("257.0.0.1").GetGroup() == boost::assign::list_of(0)); // !Valid -> !Routable() + BOOST_CHECK(CNetAddr("10.0.0.1").GetGroup() == boost::assign::list_of(0)); // RFC1918 -> !Routable() + BOOST_CHECK(CNetAddr("169.254.1.1").GetGroup() == boost::assign::list_of(0)); // RFC3927 -> !Routable() + BOOST_CHECK(CNetAddr("1.2.3.4").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // IPv4 + BOOST_CHECK(CNetAddr("::FFFF:0:102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6145 + BOOST_CHECK(CNetAddr("64:FF9B::102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6052 + BOOST_CHECK(CNetAddr("2002:102:304:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC3964 + BOOST_CHECK(CNetAddr("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC4380 + BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup() == boost::assign::list_of((unsigned char)NET_TOR)(239)); // Tor + BOOST_CHECK(CNetAddr("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(4)(112)(175)); //he.net + BOOST_CHECK(CNetAddr("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(32)(1)); //IPv6 } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index f6d06d6805..d9f3c3e467 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1) } // calculate actual merkle root and height - uint256 merkleRoot1 = block.BuildMerkleTree(); + uint256 merkleRoot1 = block.ComputeMerkleRoot(); std::vector<uint256> vTxid(nTx, uint256()); for (unsigned int j=0; j<nTx; j++) vTxid[j] = block.vtx[j].GetHash(); diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp new file mode 100644 index 0000000000..cb64ee7c69 --- /dev/null +++ b/src/test/policyestimator_tests.cpp @@ -0,0 +1,186 @@ +// 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 "policy/fees.h" +#include "txmempool.h" +#include "uint256.h" +#include "util.h" + +#include "test/test_bitcoin.h" + +#include <boost/test/unit_test.hpp> + +BOOST_FIXTURE_TEST_SUITE(policyestimator_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) +{ + CTxMemPool mpool(CFeeRate(1000)); + CAmount basefee(2000); + double basepri = 1e6; + CAmount deltaFee(100); + double deltaPri=5e5; + std::vector<CAmount> feeV[2]; + std::vector<double> priV[2]; + + // Populate vectors of increasing fees or priorities + for (int j = 0; j < 10; j++) { + //V[0] is for fee transactions + feeV[0].push_back(basefee * (j+1)); + priV[0].push_back(0); + //V[1] is for priority transactions + feeV[1].push_back(CAmount(0)); + priV[1].push_back(basepri * pow(10, j+1)); + } + + // Store the hashes of transactions that have been + // added to the mempool by their associate fee/pri + // txHashes[j] is populated with transactions either of + // fee = basefee * (j+1) OR pri = 10^6 * 10^(j+1) + std::vector<uint256> txHashes[10]; + + // Create a transaction template + CScript garbage; + for (unsigned int i = 0; i < 128; i++) + garbage.push_back('X'); + CMutableTransaction tx; + std::list<CTransaction> dummyConflicted; + tx.vin.resize(1); + tx.vin[0].scriptSig = garbage; + tx.vout.resize(1); + tx.vout[0].nValue=0LL; + CFeeRate baseRate(basefee, ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)); + + // Create a fake block + std::vector<CTransaction> block; + int blocknum = 0; + + // Loop through 200 blocks + // At a decay .998 and 4 fee transactions per block + // This makes the tx count about 1.33 per bucket, above the 1 threshold + while (blocknum < 200) { + for (int j = 0; j < 10; j++) { // For each fee/pri multiple + for (int k = 0; k < 5; k++) { // add 4 fee txs for every priority tx + tx.vin[0].prevout.n = 10000*blocknum+100*j+k; // make transaction unique + uint256 hash = tx.GetHash(); + mpool.addUnchecked(hash, CTxMemPoolEntry(tx, feeV[k/4][j], GetTime(), priV[k/4][j], blocknum, mpool.HasNoInputsOf(tx))); + txHashes[j].push_back(hash); + } + } + //Create blocks where higher fee/pri txs are included more often + for (int h = 0; h <= blocknum%10; h++) { + // 10/10 blocks add highest fee/pri transactions + // 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); + txHashes[9-h].pop_back(); + } + } + mpool.removeForBlock(block, ++blocknum, dummyConflicted); + block.clear(); + if (blocknum == 30) { + // At this point we should need to combine 5 buckets to get enough data points + // So estimateFee(1) should fail and estimateFee(2) should return somewhere around + // 8*baserate + BOOST_CHECK(mpool.estimateFee(1) == CFeeRate(0)); + BOOST_CHECK(mpool.estimateFee(2).GetFeePerK() < 8*baseRate.GetFeePerK() + deltaFee); + BOOST_CHECK(mpool.estimateFee(2).GetFeePerK() > 8*baseRate.GetFeePerK() - deltaFee); + } + } + + std::vector<CAmount> origFeeEst; + std::vector<double> origPriEst; + // 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 9*baseRate. + // Third highest feerate has 90% chance of being included by 2 blocks, + // so estimateFee(2) should return 8*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]); + BOOST_CHECK(origPriEst[i-1] <= origPriEst[i-2]); + } + BOOST_CHECK(origFeeEst[i-1] < (10-i)*baseRate.GetFeePerK() + deltaFee); + BOOST_CHECK(origFeeEst[i-1] > (10-i)*baseRate.GetFeePerK() - deltaFee); + BOOST_CHECK(origPriEst[i-1] < pow(10,10-i) * basepri + deltaPri); + BOOST_CHECK(origPriEst[i-1] > pow(10,10-i) * basepri - deltaPri); + } + + // Mine 50 more blocks with no transactions happening, estimates shouldn't change + // We haven't decayed the moving average enough so we still have enough data points in every bucket + while (blocknum < 250) + mpool.removeForBlock(block, ++blocknum, dummyConflicted); + + 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); + BOOST_CHECK(mpool.estimatePriority(i) < origPriEst[i-1] + deltaPri); + BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri); + } + + + // Mine 15 more blocks with lots of transactions happening and not getting mined + // Estimates should go up + while (blocknum < 265) { + for (int j = 0; j < 10; j++) { // For each fee/pri multiple + for (int k = 0; k < 5; k++) { // add 4 fee txs for every priority tx + tx.vin[0].prevout.n = 10000*blocknum+100*j+k; + uint256 hash = tx.GetHash(); + mpool.addUnchecked(hash, CTxMemPoolEntry(tx, feeV[k/4][j], GetTime(), priV[k/4][j], blocknum, mpool.HasNoInputsOf(tx))); + txHashes[j].push_back(hash); + } + } + mpool.removeForBlock(block, ++blocknum, dummyConflicted); + } + + for (int i = 1; i < 10;i++) { + BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); + BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri); + } + + // Mine all those transactions + // 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); + txHashes[j].pop_back(); + } + } + mpool.removeForBlock(block, 265, dummyConflicted); + block.clear(); + for (int i = 1; i < 10;i++) { + BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); + BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri); + } + + // Mine 100 more blocks where everything is mined every block + // Estimates should be below original estimates (not possible for last estimate) + while (blocknum < 365) { + for (int j = 0; j < 10; j++) { // For each fee/pri multiple + for (int k = 0; k < 5; k++) { // add 4 fee txs for every priority tx + tx.vin[0].prevout.n = 10000*blocknum+100*j+k; + uint256 hash = tx.GetHash(); + mpool.addUnchecked(hash, CTxMemPoolEntry(tx, feeV[k/4][j], GetTime(), priV[k/4][j], blocknum, mpool.HasNoInputsOf(tx))); + CTransaction btx; + if (mpool.lookup(hash, btx)) + block.push_back(btx); + } + } + mpool.removeForBlock(block, ++blocknum, dummyConflicted); + block.clear(); + } + for (int i = 1; i < 9; i++) { + BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() < origFeeEst[i-1] - deltaFee); + BOOST_CHECK(mpool.estimatePriority(i) < origPriEst[i-1] - deltaPri); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index a436749287..b6eb39bc38 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -2,8 +2,10 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "main.h" +#include "chain.h" +#include "chainparams.h" #include "pow.h" +#include "random.h" #include "util.h" #include "test/test_bitcoin.h" diff --git a/src/test/reverselock_tests.cpp b/src/test/reverselock_tests.cpp new file mode 100644 index 0000000000..e7e627ae0f --- /dev/null +++ b/src/test/reverselock_tests.cpp @@ -0,0 +1,64 @@ +// 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 "reverselock.h" +#include "test/test_bitcoin.h" + +#include <boost/test/unit_test.hpp> + +BOOST_FIXTURE_TEST_SUITE(reverselock_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(reverselock_basics) +{ + boost::mutex mutex; + boost::unique_lock<boost::mutex> lock(mutex); + + BOOST_CHECK(lock.owns_lock()); + { + reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock); + BOOST_CHECK(!lock.owns_lock()); + } + BOOST_CHECK(lock.owns_lock()); +} + +BOOST_AUTO_TEST_CASE(reverselock_errors) +{ + boost::mutex mutex; + boost::unique_lock<boost::mutex> lock(mutex); + + // Make sure trying to reverse lock an unlocked lock fails + lock.unlock(); + + BOOST_CHECK(!lock.owns_lock()); + + bool failed = false; + try { + reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock); + } catch(...) { + failed = true; + } + + 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; + + lock.lock(); + BOOST_CHECK(lock.owns_lock()); + + try { + reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock); + lock.lock(); + locked = true; + } catch(...) { + failed = true; + } + + BOOST_CHECK(locked && failed); + BOOST_CHECK(lock.owns_lock()); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 45cb551d04..1bd59497ff 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -13,35 +13,36 @@ #include <boost/algorithm/string.hpp> #include <boost/test/unit_test.hpp> +#include "univalue/univalue.h" + using namespace std; -using namespace json_spirit; -Array +UniValue createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL) { - Array result; + UniValue result(UniValue::VARR); result.push_back(nRequired); - Array addresses; + UniValue addresses(UniValue::VARR); if (address1) addresses.push_back(address1); if (address2) addresses.push_back(address2); result.push_back(addresses); return result; } -Value CallRPC(string args) +UniValue CallRPC(string args) { vector<string> vArgs; boost::split(vArgs, args, boost::is_any_of(" \t")); string strMethod = vArgs[0]; vArgs.erase(vArgs.begin()); - Array params = RPCConvertValues(strMethod, vArgs); + UniValue params = RPCConvertValues(strMethod, vArgs); rpcfn_type method = tableRPC[strMethod]->actor; try { - Value result = (*method)(params, false); + UniValue result = (*method)(params, false); return result; } - catch (const Object& objError) { + catch (const UniValue& objError) { throw runtime_error(find_value(objError, "message").get_str()); } } @@ -52,7 +53,7 @@ BOOST_FIXTURE_TEST_SUITE(rpc_tests, TestingSetup) BOOST_AUTO_TEST_CASE(rpc_rawparams) { // Test raw transaction API argument handling - Value r; + UniValue r; BOOST_CHECK_THROW(CallRPC("getrawtransaction"), runtime_error); BOOST_CHECK_THROW(CallRPC("getrawtransaction not_hex"), runtime_error); @@ -92,7 +93,7 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams) BOOST_AUTO_TEST_CASE(rpc_rawsign) { - Value r; + UniValue r; // input is a 1-of-2 multisig (so is output): string prevout = "[{\"txid\":\"b4cc287e58f87cdae59417329f710f3ecd75a4ee1d2872b7248f50977c8493f3\"," @@ -109,27 +110,71 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign) BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == true); } +BOOST_AUTO_TEST_CASE(rpc_createraw_op_return) +{ + BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"68656c6c6f776f726c64\"}")); + + // Allow more than one data transaction output + BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"68656c6c6f776f726c64\",\"data\":\"68656c6c6f776f726c64\"}")); + + // Key not "data" (bad address) + BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"somedata\":\"68656c6c6f776f726c64\"}"), runtime_error); + + // Bad hex encoding of data output + BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"12345\"}"), runtime_error); + BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"12345g\"}"), runtime_error); + + // Data 81 bytes long + BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081\"}")); +} + BOOST_AUTO_TEST_CASE(rpc_format_monetary_values) { - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(0LL), false), "0.00000000"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(1LL), false), "0.00000001"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(17622195LL), false), "0.17622195"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(50000000LL), false), "0.50000000"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(89898989LL), false), "0.89898989"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(100000000LL), false), "1.00000000"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(2099999999999990LL), false), "20999999.99999990"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(2099999999999999LL), false), "20999999.99999999"); + BOOST_CHECK(ValueFromAmount(0LL).write() == "0.00000000"); + BOOST_CHECK(ValueFromAmount(1LL).write() == "0.00000001"); + BOOST_CHECK(ValueFromAmount(17622195LL).write() == "0.17622195"); + BOOST_CHECK(ValueFromAmount(50000000LL).write() == "0.50000000"); + BOOST_CHECK(ValueFromAmount(89898989LL).write() == "0.89898989"); + BOOST_CHECK(ValueFromAmount(100000000LL).write() == "1.00000000"); + BOOST_CHECK(ValueFromAmount(2099999999999990LL).write() == "20999999.99999990"); + BOOST_CHECK(ValueFromAmount(2099999999999999LL).write() == "20999999.99999999"); + + BOOST_CHECK_EQUAL(ValueFromAmount(0).write(), "0.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount((COIN/10000)*123456789).write(), "12345.67890000"); + BOOST_CHECK_EQUAL(ValueFromAmount(-COIN).write(), "-1.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(-COIN/10).write(), "-0.10000000"); + + BOOST_CHECK_EQUAL(ValueFromAmount(COIN*100000000).write(), "100000000.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN*10000000).write(), "10000000.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN*1000000).write(), "1000000.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN*100000).write(), "100000.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN*10000).write(), "10000.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN*1000).write(), "1000.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN*100).write(), "100.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN*10).write(), "10.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN).write(), "1.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN/10).write(), "0.10000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN/100).write(), "0.01000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN/1000).write(), "0.00100000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN/10000).write(), "0.00010000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN/100000).write(), "0.00001000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN/1000000).write(), "0.00000100"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN/10000000).write(), "0.00000010"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN/100000000).write(), "0.00000001"); } -static Value ValueFromString(const std::string &str) +static UniValue ValueFromString(const std::string &str) { - Value value; - BOOST_CHECK(read_string(str, value)); + UniValue value; + BOOST_CHECK(value.setNumStr(str)); return value; } BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values) { + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("-0.00000001")), UniValue); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0")), 0LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.00000000")), 0LL); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.00000001")), 1LL); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.17622195")), 17622195LL); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.5")), 50000000LL); @@ -138,21 +183,128 @@ BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values) BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("1.00000000")), 100000000LL); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("20999999.9999999")), 2099999999999990LL); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("20999999.99999999")), 2099999999999999LL); + + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("1e-8")), COIN/100000000); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.1e-7")), COIN/100000000); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.01e-6")), COIN/100000000); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.0000000000000000000000000000000000000000000000000000000000000000000000000001e+68")), COIN/100000000); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("10000000000000000000000000000000000000000000000000000000000000000e-64")), COIN); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000e64")), COIN); + + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("1e-9")), UniValue); //should fail + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("0.000000019")), UniValue); //should fail + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.00000001000000")), 1LL); //should pass, cut trailing 0 + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("19e-9")), UniValue); //should fail + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.19e-6")), 19); //should pass, leading 0 is present + + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("92233720368.54775808")), UniValue); //overflow error + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("1e+11")), UniValue); //overflow error + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("1e11")), UniValue); //overflow error signless + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("93e+9")), UniValue); //overflow error } -BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr) +BOOST_AUTO_TEST_CASE(json_parse_errors) { - // Check IPv4 addresses - BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("1.2.3.4")).ToString(), "1.2.3.4"); - BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("127.0.0.1")).ToString(), "127.0.0.1"); - // Check IPv6 addresses - BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::1")).ToString(), "::1"); - BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("123:4567:89ab:cdef:123:4567:89ab:cdef")).ToString(), - "123:4567:89ab:cdef:123:4567:89ab:cdef"); - // v4 compatible must be interpreted as IPv4 - BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::0:127.0.0.1")).ToString(), "127.0.0.1"); - // v4 mapped must be interpreted as IPv4 - BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::ffff:127.0.0.1")).ToString(), "127.0.0.1"); + // Valid + BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("1.0").get_real(), 1.0); + // Valid, with leading or trailing whitespace + BOOST_CHECK_EQUAL(ParseNonRFCJSONValue(" 1.0").get_real(), 1.0); + BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("1.0 ").get_real(), 1.0); + + BOOST_CHECK_THROW(AmountFromValue(ParseNonRFCJSONValue(".19e-6")), std::runtime_error); //should fail, missing leading 0, therefore invalid JSON + BOOST_CHECK_EQUAL(AmountFromValue(ParseNonRFCJSONValue("0.00000000000000000000000000000000000001e+30 ")), 1); + // Invalid, initial garbage + BOOST_CHECK_THROW(ParseNonRFCJSONValue("[1.0"), std::runtime_error); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("a1.0"), std::runtime_error); + // Invalid, trailing garbage + BOOST_CHECK_THROW(ParseNonRFCJSONValue("1.0sds"), std::runtime_error); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("1.0]"), std::runtime_error); + // BTC addresses should fail parsing + BOOST_CHECK_THROW(ParseNonRFCJSONValue("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"), std::runtime_error); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"), std::runtime_error); +} + +BOOST_AUTO_TEST_CASE(rpc_ban) +{ + BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); + + UniValue r; + BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0 add"))); + BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.0:8334")), runtime_error); //portnumber for setban not allowed + BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + UniValue ar = r.get_array(); + 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(r = CallRPC(string("listbanned"))); + ar = r.get_array(); + BOOST_CHECK_EQUAL(ar.size(), 0); + + BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0/24 add 1607731200 true"))); + BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + ar = r.get_array(); + o1 = ar[0].get_obj(); + adr = find_value(o1, "address"); + UniValue banned_until = find_value(o1, "banned_until"); + BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24"); + BOOST_CHECK_EQUAL(banned_until.get_int64(), 1607731200); // absolute time check + + BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); + + BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0/24 add 200"))); + BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + ar = r.get_array(); + o1 = ar[0].get_obj(); + 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(); + BOOST_CHECK(banned_until.get_int64() > now); + BOOST_CHECK(banned_until.get_int64()-now <= 200); + + // 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(r = CallRPC(string("listbanned"))); + ar = r.get_array(); + BOOST_CHECK_EQUAL(ar.size(), 0); + + BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0/255.255.0.0 add"))); + BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.1.1 add")), runtime_error); + + BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); + BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + ar = r.get_array(); + BOOST_CHECK_EQUAL(ar.size(), 0); + + + BOOST_CHECK_THROW(r = CallRPC(string("setban test add")), runtime_error); //invalid IP + + //IPv6 tests + BOOST_CHECK_NO_THROW(r = CallRPC(string("setban FE80:0000:0000:0000:0202:B3FF:FE1E:8329 add"))); + BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + ar = r.get_array(); + o1 = ar[0].get_obj(); + adr = find_value(o1, "address"); + BOOST_CHECK_EQUAL(adr.get_str(), "fe80::202:b3ff:fe1e:8329/128"); + + BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); + BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 2001:db8::/ffff:fffc:0:0:0:0:0:0 add"))); + BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + ar = r.get_array(); + o1 = ar[0].get_obj(); + adr = find_value(o1, "address"); + BOOST_CHECK_EQUAL(adr.get_str(), "2001:db8::/30"); + + BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); + BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/128 add"))); + BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + ar = r.get_array(); + o1 = ar[0].get_obj(); + adr = find_value(o1, "address"); + BOOST_CHECK_EQUAL(adr.get_str(), "2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/128"); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 4d5e92cbd4..52f41be8ae 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -14,11 +14,12 @@ #include <boost/algorithm/string.hpp> #include <boost/test/unit_test.hpp> +#include "univalue/univalue.h" + using namespace std; -using namespace json_spirit; -extern Array createArgs(int nRequired, const char* address1 = NULL, const char* address2 = NULL); -extern Value CallRPC(string args); +extern UniValue createArgs(int nRequired, const char* address1 = NULL, const char* address2 = NULL); +extern UniValue CallRPC(string args); extern CWallet* pwalletMain; @@ -26,8 +27,6 @@ BOOST_FIXTURE_TEST_SUITE(rpc_wallet_tests, TestingSetup) BOOST_AUTO_TEST_CASE(rpc_addmultisig) { - LOCK(pwalletMain->cs_wallet); - rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor; // old, 65-byte-long: @@ -35,7 +34,7 @@ BOOST_AUTO_TEST_CASE(rpc_addmultisig) // new, compressed: const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4"; - Value v; + UniValue v; CBitcoinAddress address; BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false)); address.SetString(v.get_str()); @@ -66,26 +65,29 @@ BOOST_AUTO_TEST_CASE(rpc_addmultisig) BOOST_AUTO_TEST_CASE(rpc_wallet) { // Test RPC calls for various wallet statistics - Value r; - - LOCK2(cs_main, pwalletMain->cs_wallet); - - CPubKey demoPubkey = pwalletMain->GenerateNewKey(); - CBitcoinAddress demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID())); - Value retValue; + UniValue r; + CPubKey demoPubkey; + CBitcoinAddress demoAddress; + UniValue retValue; string strAccount = "walletDemoAccount"; - string strPurpose = "receive"; - BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */ - CWalletDB walletdb(pwalletMain->strWalletFile); - CAccount account; - account.vchPubKey = demoPubkey; - pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, strPurpose); - walletdb.WriteAccount(strAccount, account); - }); - - CPubKey setaccountDemoPubkey = pwalletMain->GenerateNewKey(); - CBitcoinAddress setaccountDemoAddress = CBitcoinAddress(CTxDestination(setaccountDemoPubkey.GetID())); - + CBitcoinAddress setaccountDemoAddress; + { + LOCK(pwalletMain->cs_wallet); + + demoPubkey = pwalletMain->GenerateNewKey(); + demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID())); + string strPurpose = "receive"; + BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */ + CWalletDB walletdb(pwalletMain->strWalletFile); + CAccount account; + account.vchPubKey = demoPubkey; + pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, strPurpose); + walletdb.WriteAccount(strAccount, account); + }); + + CPubKey setaccountDemoPubkey = pwalletMain->GenerateNewKey(); + setaccountDemoAddress = CBitcoinAddress(CTxDestination(setaccountDemoPubkey.GetID())); + } /********************************* * setaccount *********************************/ @@ -213,9 +215,15 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) *********************************/ BOOST_CHECK_THROW(CallRPC("getaddressesbyaccount"), runtime_error); BOOST_CHECK_NO_THROW(retValue = CallRPC("getaddressesbyaccount " + strAccount)); - Array arr = retValue.get_array(); + UniValue arr = retValue.get_array(); BOOST_CHECK(arr.size() > 0); BOOST_CHECK(CBitcoinAddress(arr[0].get_str()).Get() == demoAddress.Get()); + + /********************************* + * fundrawtransaction + *********************************/ + BOOST_CHECK_THROW(CallRPC("fundrawtransaction 28z"), runtime_error); + BOOST_CHECK_THROW(CallRPC("fundrawtransaction 01000000000180969800000000001976a91450ce0a4b0ee0ddeb633da85199728b940ac3fe9488ac00000000"), runtime_error); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp new file mode 100644 index 0000000000..cb1a427db0 --- /dev/null +++ b/src/test/scheduler_tests.cpp @@ -0,0 +1,119 @@ +// 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 "random.h" +#include "scheduler.h" + +#include "test/test_bitcoin.h" + +#include <boost/bind.hpp> +#include <boost/random/mersenne_twister.hpp> +#include <boost/random/uniform_int_distribution.hpp> +#include <boost/thread.hpp> +#include <boost/test/unit_test.hpp> + +BOOST_AUTO_TEST_SUITE(scheduler_tests) + +static void microTask(CScheduler& s, boost::mutex& mutex, int& counter, int delta, boost::chrono::system_clock::time_point rescheduleTime) +{ + { + boost::unique_lock<boost::mutex> lock(mutex); + counter += delta; + } + boost::chrono::system_clock::time_point noTime = boost::chrono::system_clock::time_point::min(); + if (rescheduleTime != noTime) { + CScheduler::Function f = boost::bind(µTask, boost::ref(s), boost::ref(mutex), boost::ref(counter), -delta + 1, noTime); + s.schedule(f, rescheduleTime); + } +} + +static void MicroSleep(uint64_t n) +{ +#if defined(HAVE_WORKING_BOOST_SLEEP_FOR) + boost::this_thread::sleep_for(boost::chrono::microseconds(n)); +#elif defined(HAVE_WORKING_BOOST_SLEEP) + boost::this_thread::sleep(boost::posix_time::microseconds(n)); +#else + //should never get here + #error missing boost sleep implementation +#endif +} + +BOOST_AUTO_TEST_CASE(manythreads) +{ + seed_insecure_rand(false); + + // Stress test: hundreds of microsecond-scheduled tasks, + // serviced by 10 threads. + // + // So... ten shared counters, which if all the tasks execute + // properly will sum to the number of tasks done. + // Each task adds or subtracts from one of the counters a + // random amount, and then schedules another task 0-1000 + // microseconds in the future to subtract or add from + // the counter -random_amount+1, so in the end the shared + // counters should sum to the number of initial tasks performed. + CScheduler microTasks; + + boost::mutex counterMutex[10]; + int counter[10] = { 0 }; + boost::random::mt19937 rng(insecure_rand()); + boost::random::uniform_int_distribution<> zeroToNine(0, 9); + boost::random::uniform_int_distribution<> randomMsec(-11, 1000); + boost::random::uniform_int_distribution<> randomDelta(-1000, 1000); + + boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now(); + boost::chrono::system_clock::time_point now = start; + boost::chrono::system_clock::time_point first, last; + size_t nTasks = microTasks.getQueueInfo(first, last); + BOOST_CHECK(nTasks == 0); + + for (int i = 0; i < 100; i++) { + boost::chrono::system_clock::time_point t = now + boost::chrono::microseconds(randomMsec(rng)); + boost::chrono::system_clock::time_point tReschedule = now + boost::chrono::microseconds(500 + randomMsec(rng)); + int whichCounter = zeroToNine(rng); + CScheduler::Function f = boost::bind(µTask, boost::ref(microTasks), + boost::ref(counterMutex[whichCounter]), boost::ref(counter[whichCounter]), + randomDelta(rng), tReschedule); + microTasks.schedule(f, t); + } + nTasks = microTasks.getQueueInfo(first, last); + BOOST_CHECK(nTasks == 100); + BOOST_CHECK(first < last); + BOOST_CHECK(last > now); + + // As soon as these are created they will start running and servicing the queue + boost::thread_group microThreads; + for (int i = 0; i < 5; i++) + microThreads.create_thread(boost::bind(&CScheduler::serviceQueue, µTasks)); + + MicroSleep(600); + now = boost::chrono::system_clock::now(); + + // More threads and more tasks: + for (int i = 0; i < 5; i++) + microThreads.create_thread(boost::bind(&CScheduler::serviceQueue, µTasks)); + for (int i = 0; i < 100; i++) { + boost::chrono::system_clock::time_point t = now + boost::chrono::microseconds(randomMsec(rng)); + boost::chrono::system_clock::time_point tReschedule = now + boost::chrono::microseconds(500 + randomMsec(rng)); + int whichCounter = zeroToNine(rng); + CScheduler::Function f = boost::bind(µTask, boost::ref(microTasks), + boost::ref(counterMutex[whichCounter]), boost::ref(counter[whichCounter]), + randomDelta(rng), tReschedule); + microTasks.schedule(f, t); + } + + // Drain the task queue then exit threads + microTasks.stop(true); + microThreads.join_all(); // ... wait until all the threads are done + + int counterSum = 0; + for (int i = 0; i < 10; i++) { + BOOST_CHECK(counter[i] != 0); + counterSum += counter[i]; + } + BOOST_CHECK_EQUAL(counterSum, 200); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index c8cfe28729..16c9a4a868 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -5,6 +5,7 @@ #include "key.h" #include "keystore.h" #include "main.h" +#include "policy/policy.h" #include "script/script.h" #include "script/script_error.h" #include "script/sign.h" diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index c0614cca43..225da0801a 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -8,11 +8,11 @@ #include "core_io.h" #include "key.h" #include "keystore.h" -#include "main.h" #include "script/script.h" #include "script/script_error.h" #include "script/sign.h" #include "util.h" +#include "utilstrencodings.h" #include "test/test_bitcoin.h" #if defined(HAVE_CONSENSUS_LIB) @@ -26,12 +26,10 @@ #include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" + +#include "univalue/univalue.h" using namespace std; -using namespace json_spirit; // Uncomment if you want to output updated JSON tests. // #define UPDATE_JSON_TESTS @@ -41,15 +39,15 @@ static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; unsigned int ParseScriptFlags(string strFlags); string FormatScriptFlags(unsigned int flags); -Array +UniValue read_json(const std::string& jsondata) { - Value v; + UniValue v; - if (!read_string(jsondata, v) || v.type() != array_type) + if (!v.read(jsondata) || !v.isArray()) { BOOST_ERROR("Parse error."); - return Array(); + return UniValue(UniValue::VARR); } return v.get_array(); } @@ -295,10 +293,10 @@ public: return *this; } - Array GetJSON() + UniValue GetJSON() { DoPush(); - Array array; + UniValue array(UniValue::VARR); array.push_back(FormatScript(spendTx.vin[0].scriptSig)); array.push_back(FormatScript(creditTx.vout[0].scriptPubKey)); array.push_back(FormatScriptFlags(flags)); @@ -582,14 +580,16 @@ BOOST_AUTO_TEST_CASE(script_build) std::set<std::string> tests_bad; { - Array json_good = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); - Array json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); + 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))); - BOOST_FOREACH(Value& tv, json_good) { - tests_good.insert(write_string(Value(tv.get_array()), true)); + for (unsigned int idx = 0; idx < json_good.size(); idx++) { + const UniValue& tv = json_good[idx]; + tests_good.insert(tv.get_array().write()); } - BOOST_FOREACH(Value& tv, json_bad) { - tests_bad.insert(write_string(Value(tv.get_array()), true)); + for (unsigned int idx = 0; idx < json_bad.size(); idx++) { + const UniValue& tv = json_bad[idx]; + tests_bad.insert(tv.get_array().write()); } } @@ -598,7 +598,7 @@ BOOST_AUTO_TEST_CASE(script_build) BOOST_FOREACH(TestBuilder& test, good) { test.Test(true); - std::string str = write_string(Value(test.GetJSON()), true); + std::string str = test.GetJSON().write(); #ifndef UPDATE_JSON_TESTS if (tests_good.count(str) == 0) { BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " + test.GetComment()); @@ -608,7 +608,7 @@ BOOST_AUTO_TEST_CASE(script_build) } BOOST_FOREACH(TestBuilder& test, bad) { test.Test(false); - std::string str = write_string(Value(test.GetJSON()), true); + std::string str = test.GetJSON().write(); #ifndef UPDATE_JSON_TESTS if (tests_bad.count(str) == 0) { BOOST_CHECK_MESSAGE(false, "Missing auto script_invalid test: " + test.GetComment()); @@ -634,12 +634,11 @@ BOOST_AUTO_TEST_CASE(script_valid) // Inner arrays are [ "scriptSig", "scriptPubKey", "flags" ] // ... where scriptSig and scriptPubKey are stringified // scripts. - Array 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_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - string strTest = write_string(tv, false); + 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) { @@ -660,13 +659,12 @@ BOOST_AUTO_TEST_CASE(script_valid) BOOST_AUTO_TEST_CASE(script_invalid) { // Scripts that should evaluate as invalid - Array tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); + UniValue tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - string strTest = write_string(tv, false); - if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments) + 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() != 1) { BOOST_ERROR("Bad test: " << strTest); @@ -842,7 +840,7 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); -} +} BOOST_AUTO_TEST_CASE(script_combineSigs) { @@ -985,4 +983,34 @@ BOOST_AUTO_TEST_CASE(script_IsPushOnly_on_invalid_scripts) BOOST_CHECK(!CScript(direct, direct+sizeof(direct)).IsPushOnly()); } +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)); + + string derSig("304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090"); + string pubKey("03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2"); + vector<unsigned char> vchPubKey = ToByteVector(ParseHex(pubKey)); + + BOOST_CHECK_EQUAL(derSig + "00 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "00")) << vchPubKey, true)); + BOOST_CHECK_EQUAL(derSig + "80 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "80")) << vchPubKey, true)); + BOOST_CHECK_EQUAL(derSig + "[ALL] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "01")) << vchPubKey, true)); + BOOST_CHECK_EQUAL(derSig + "[NONE] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "02")) << vchPubKey, true)); + BOOST_CHECK_EQUAL(derSig + "[SINGLE] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "03")) << vchPubKey, true)); + BOOST_CHECK_EQUAL(derSig + "[ALL|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "81")) << vchPubKey, true)); + BOOST_CHECK_EQUAL(derSig + "[NONE|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "82")) << vchPubKey, true)); + BOOST_CHECK_EQUAL(derSig + "[SINGLE|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "83")) << vchPubKey, true)); + + BOOST_CHECK_EQUAL(derSig + "00 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "00")) << vchPubKey)); + BOOST_CHECK_EQUAL(derSig + "80 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "80")) << vchPubKey)); + BOOST_CHECK_EQUAL(derSig + "01 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "01")) << vchPubKey)); + BOOST_CHECK_EQUAL(derSig + "02 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "02")) << vchPubKey)); + BOOST_CHECK_EQUAL(derSig + "03 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "03")) << vchPubKey)); + BOOST_CHECK_EQUAL(derSig + "81 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "81")) << vchPubKey)); + BOOST_CHECK_EQUAL(derSig + "82 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "82")) << vchPubKey)); + BOOST_CHECK_EQUAL(derSig + "83 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "83")) << vchPubKey)); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp index 24c7dd3d5a..d95724dbe1 100644 --- a/src/test/scriptnum_tests.cpp +++ b/src/test/scriptnum_tests.cpp @@ -145,7 +145,7 @@ static void RunCreate(const int64_t& num) { CheckCreateInt(num); CScriptNum scriptnum(num); - if (scriptnum.getvch().size() <= CScriptNum::nMaxNumSize) + if (scriptnum.getvch().size() <= CScriptNum::nDefaultMaxNumSize) CheckCreateVch(num); else { diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index afb7a41bbd..4b96461562 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -2,25 +2,27 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "consensus/validation.h" #include "data/sighash.json.h" -#include "main.h" +#include "hash.h" +#include "main.h" // For CheckTransaction #include "random.h" -#include "serialize.h" -#include "script/script.h" #include "script/interpreter.h" +#include "script/script.h" +#include "serialize.h" +#include "streams.h" +#include "test/test_bitcoin.h" #include "util.h" +#include "utilstrencodings.h" #include "version.h" -#include "test/test_bitcoin.h" #include <iostream> #include <boost/test/unit_test.hpp> -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" -using namespace json_spirit; -extern Array read_json(const std::string& jsondata); +#include "univalue/univalue.h" + +extern UniValue read_json(const std::string& jsondata); // Old script.cpp SignatureHash function uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) @@ -167,12 +169,11 @@ BOOST_AUTO_TEST_CASE(sighash_test) // Goal: check that SignatureHash generates correct hash BOOST_AUTO_TEST_CASE(sighash_from_data) { - Array tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash))); + UniValue tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash))); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + UniValue test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 1) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index 86a4bc6727..a904e3862f 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.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 "main.h" +#include "chain.h" #include "random.h" #include "util.h" #include "test/test_bitcoin.h" diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 4057eccbed..8d81275a6f 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -6,7 +6,13 @@ #include "test_bitcoin.h" +#include "chainparams.h" +#include "consensus/consensus.h" +#include "consensus/validation.h" +#include "key.h" #include "main.h" +#include "miner.h" +#include "pubkey.h" #include "random.h" #include "txdb.h" #include "ui_interface.h" @@ -26,18 +32,22 @@ CWallet* pwalletMain; extern bool fPrintToConsole; extern void noui_connect(); -BasicTestingSetup::BasicTestingSetup() +BasicTestingSetup::BasicTestingSetup(CBaseChainParams::Network network) { + ECC_Start(); SetupEnvironment(); fPrintToDebugLog = false; // don't want to write to debug.log file fCheckBlockIndex = true; - SelectParams(CBaseChainParams::MAIN); + SelectParams(network); + noui_connect(); } + BasicTestingSetup::~BasicTestingSetup() { + ECC_Stop(); } -TestingSetup::TestingSetup() +TestingSetup::TestingSetup(CBaseChainParams::Network network) : BasicTestingSetup(network) { #ifdef ENABLE_WALLET bitdb.MakeMock(); @@ -83,6 +93,51 @@ TestingSetup::~TestingSetup() boost::filesystem::remove_all(pathTemp); } +TestChain100Setup::TestChain100Setup() : TestingSetup(CBaseChainParams::REGTEST) +{ + // Generate a 100-block chain: + coinbaseKey.MakeNewKey(true); + CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; + for (int i = 0; i < COINBASE_MATURITY; i++) + { + std::vector<CMutableTransaction> noTxns; + CBlock b = CreateAndProcessBlock(noTxns, scriptPubKey); + coinbaseTxns.push_back(b.vtx[0]); + } +} + +// +// Create a new block with just given transactions, coinbase paying to +// scriptPubKey, and try to add it to the current chain. +// +CBlock +TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey) +{ + CBlockTemplate *pblocktemplate = CreateNewBlock(scriptPubKey); + CBlock& block = pblocktemplate->block; + + // Replace mempool-selected txns with just coinbase plus passed-in txns: + block.vtx.resize(1); + BOOST_FOREACH(const CMutableTransaction& tx, txns) + block.vtx.push_back(tx); + // IncrementExtraNonce creates a valid coinbase and merkleRoot + unsigned int extraNonce = 0; + IncrementExtraNonce(&block, chainActive.Tip(), extraNonce); + + while (!CheckProofOfWork(block.GetHash(), block.nBits, Params(CBaseChainParams::REGTEST).GetConsensus())) ++block.nNonce; + + CValidationState state; + ProcessNewBlock(state, NULL, &block, true, NULL); + + CBlock result = block; + delete pblocktemplate; + return result; +} + +TestChain100Setup::~TestChain100Setup() +{ +} + void Shutdown(void* parg) { exit(0); diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index 2f75332d40..b9314d0611 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -1,6 +1,8 @@ #ifndef BITCOIN_TEST_TEST_BITCOIN_H #define BITCOIN_TEST_TEST_BITCOIN_H +#include "chainparamsbase.h" +#include "key.h" #include "txdb.h" #include <boost/filesystem.hpp> @@ -10,7 +12,7 @@ * This just configures logging and chain parameters. */ struct BasicTestingSetup { - BasicTestingSetup(); + BasicTestingSetup(CBaseChainParams::Network network = CBaseChainParams::MAIN); ~BasicTestingSetup(); }; @@ -23,8 +25,30 @@ struct TestingSetup: public BasicTestingSetup { boost::filesystem::path pathTemp; boost::thread_group threadGroup; - TestingSetup(); + TestingSetup(CBaseChainParams::Network network = CBaseChainParams::MAIN); ~TestingSetup(); }; +class CBlock; +struct CMutableTransaction; +class CScript; + +// +// Testing fixture that pre-creates a +// 100-block REGTEST-mode block chain +// +struct TestChain100Setup : public TestingSetup { + TestChain100Setup(); + + // Create a new block with just given transactions, coinbase paying to + // scriptPubKey, and try to add it to the current chain. + CBlock CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns, + const CScript& scriptPubKey); + + ~TestChain100Setup(); + + std::vector<CTransaction> coinbaseTxns; // For convenience, coinbase transactions + CKey coinbaseKey; // private/public key needed to spend coinbase transactions +}; + #endif diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 2a3083316e..e70ebddc2f 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -7,27 +7,31 @@ #include "test/test_bitcoin.h" #include "clientversion.h" +#include "consensus/validation.h" +#include "core_io.h" #include "key.h" #include "keystore.h" -#include "main.h" +#include "main.h" // For CheckTransaction +#include "policy/policy.h" #include "script/script.h" #include "script/script_error.h" -#include "core_io.h" +#include "utilstrencodings.h" #include <map> #include <string> #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/split.hpp> +#include <boost/assign/list_of.hpp> #include <boost/test/unit_test.hpp> #include <boost/assign/list_of.hpp> -#include "json/json_spirit_writer_template.h" + +#include "univalue/univalue.h" using namespace std; -using namespace json_spirit; // In script_tests.cpp -extern Array read_json(const std::string& jsondata); +extern UniValue read_json(const std::string& jsondata); static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of (string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE) @@ -39,7 +43,8 @@ static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of (string("MINIMALDATA"), (unsigned int)SCRIPT_VERIFY_MINIMALDATA) (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("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK) + (string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY); unsigned int ParseScriptFlags(string strFlags) { @@ -87,32 +92,31 @@ BOOST_AUTO_TEST_CASE(tx_valid) // ... where all scripts are stringified scripts. // // verifyFlags is a comma separated list of script verification flags to apply, or "NONE" - Array tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid))); + UniValue tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid))); ScriptError err; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - string strTest = write_string(tv, false); - if (test[0].type() == array_type) + for (unsigned int idx = 0; idx < tests.size(); idx++) { + UniValue test = tests[idx]; + string strTest = test.write(); + if (test[0].isArray()) { - if (test.size() != 3 || test[1].type() != str_type || test[2].type() != str_type) + if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) { BOOST_ERROR("Bad test: " << strTest); continue; } map<COutPoint, CScript> mapprevOutScriptPubKeys; - Array inputs = test[0].get_array(); + UniValue inputs = test[0].get_array(); bool fValid = true; - BOOST_FOREACH(Value& input, inputs) - { - if (input.type() != array_type) + for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { + const UniValue& input = inputs[inpIdx]; + if (!input.isArray()) { fValid = false; break; } - Array vinput = input.get_array(); + UniValue vinput = input.get_array(); if (vinput.size() != 3) { fValid = false; @@ -163,32 +167,31 @@ BOOST_AUTO_TEST_CASE(tx_invalid) // ... where all scripts are stringified scripts. // // verifyFlags is a comma separated list of script verification flags to apply, or "NONE" - Array tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid))); + UniValue tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid))); ScriptError err; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - string strTest = write_string(tv, false); - if (test[0].type() == array_type) + for (unsigned int idx = 0; idx < tests.size(); idx++) { + UniValue test = tests[idx]; + string strTest = test.write(); + if (test[0].isArray()) { - if (test.size() != 3 || test[1].type() != str_type || test[2].type() != str_type) + if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) { BOOST_ERROR("Bad test: " << strTest); continue; } map<COutPoint, CScript> mapprevOutScriptPubKeys; - Array inputs = test[0].get_array(); + UniValue inputs = test[0].get_array(); bool fValid = true; - BOOST_FOREACH(Value& input, inputs) - { - if (input.type() != array_type) + for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { + const UniValue& input = inputs[inpIdx]; + if (!input.isArray()) { fValid = false; break; } - Array vinput = input.get_array(); + UniValue vinput = input.get_array(); if (vinput.size() != 3) { fValid = false; diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp new file mode 100644 index 0000000000..edad18644e --- /dev/null +++ b/src/test/txvalidationcache_tests.cpp @@ -0,0 +1,86 @@ +// 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. + +#include "consensus/validation.h" +#include "key.h" +#include "main.h" +#include "miner.h" +#include "pubkey.h" +#include "txmempool.h" +#include "random.h" +#include "script/standard.h" +#include "test/test_bitcoin.h" +#include "utiltime.h" + +#include <boost/test/unit_test.hpp> + +BOOST_AUTO_TEST_SUITE(tx_validationcache_tests) + +static bool +ToMemPool(CMutableTransaction& tx) +{ + LOCK(cs_main); + + CValidationState state; + return AcceptToMemoryPool(mempool, state, tx, false, NULL, false); +} + +BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) +{ + // Make sure skipping validation of transctions that were + // validated going into the memory pool does not allow + // double-spends in blocks to pass validation when they should not. + + CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; + + // Create a double-spend of mature coinbase txn: + std::vector<CMutableTransaction> spends; + spends.resize(2); + for (int i = 0; i < 2; i++) + { + spends[i].vin.resize(1); + spends[i].vin[0].prevout.hash = coinbaseTxns[0].GetHash(); + spends[i].vin[0].prevout.n = 0; + spends[i].vout.resize(1); + spends[i].vout[0].nValue = 11*CENT; + spends[i].vout[0].scriptPubKey = scriptPubKey; + + // Sign: + std::vector<unsigned char> vchSig; + uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL); + BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); + vchSig.push_back((unsigned char)SIGHASH_ALL); + spends[i].vin[0].scriptSig << vchSig; + } + + CBlock block; + + // Test 1: block with both of those transactions should be rejected. + block = CreateAndProcessBlock(spends, scriptPubKey); + BOOST_CHECK(chainActive.Tip()->GetBlockHash() != block.GetHash()); + + // Test 2: ... and should be rejected if spend1 is in the memory pool + BOOST_CHECK(ToMemPool(spends[0])); + block = CreateAndProcessBlock(spends, scriptPubKey); + BOOST_CHECK(chainActive.Tip()->GetBlockHash() != block.GetHash()); + mempool.clear(); + + // Test 3: ... and should be rejected if spend2 is in the memory pool + BOOST_CHECK(ToMemPool(spends[1])); + block = CreateAndProcessBlock(spends, scriptPubKey); + BOOST_CHECK(chainActive.Tip()->GetBlockHash() != block.GetHash()); + mempool.clear(); + + // Final sanity test: first spend in mempool, second in block, that's OK: + std::vector<CMutableTransaction> oneSpend; + oneSpend.push_back(spends[0]); + BOOST_CHECK(ToMemPool(spends[1])); + block = CreateAndProcessBlock(oneSpend, scriptPubKey); + BOOST_CHECK(chainActive.Tip()->GetBlockHash() == block.GetHash()); + // spends[1] should have been removed from the mempool when the + // block with spends[0] is accepted: + BOOST_CHECK_EQUAL(mempool.size(), 0); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index 8cecfbf651..ee31c0955b 100644 --- a/src/test/univalue_tests.cpp +++ b/src/test/univalue_tests.cpp @@ -63,6 +63,48 @@ BOOST_AUTO_TEST_CASE(univalue_constructor) BOOST_CHECK_EQUAL(v9.getValStr(), "zappa"); } +BOOST_AUTO_TEST_CASE(univalue_typecheck) +{ + UniValue v1; + BOOST_CHECK(v1.setNumStr("1")); + BOOST_CHECK(v1.isNum()); + BOOST_CHECK_THROW(v1.get_bool(), runtime_error); + + UniValue v2; + BOOST_CHECK(v2.setBool(true)); + BOOST_CHECK_EQUAL(v2.get_bool(), true); + BOOST_CHECK_THROW(v2.get_int(), runtime_error); + + UniValue v3; + BOOST_CHECK(v3.setNumStr("32482348723847471234")); + BOOST_CHECK_THROW(v3.get_int64(), runtime_error); + BOOST_CHECK(v3.setNumStr("1000")); + BOOST_CHECK_EQUAL(v3.get_int64(), 1000); + + UniValue v4; + BOOST_CHECK(v4.setNumStr("2147483648")); + BOOST_CHECK_EQUAL(v4.get_int64(), 2147483648); + BOOST_CHECK_THROW(v4.get_int(), runtime_error); + BOOST_CHECK(v4.setNumStr("1000")); + BOOST_CHECK_EQUAL(v4.get_int(), 1000); + BOOST_CHECK_THROW(v4.get_str(), runtime_error); + BOOST_CHECK_EQUAL(v4.get_real(), 1000); + BOOST_CHECK_THROW(v4.get_array(), runtime_error); + BOOST_CHECK_THROW(v4.getKeys(), runtime_error); + BOOST_CHECK_THROW(v4.getValues(), runtime_error); + BOOST_CHECK_THROW(v4.get_obj(), runtime_error); + + UniValue v5; + BOOST_CHECK(v5.read("[true, 10]")); + BOOST_CHECK_NO_THROW(v5.get_array()); + std::vector<UniValue> vals = v5.getValues(); + BOOST_CHECK_THROW(vals[0].get_int(), runtime_error); + BOOST_CHECK_EQUAL(vals[0].get_bool(), true); + + BOOST_CHECK_EQUAL(vals[1].get_int(), 10); + BOOST_CHECK_THROW(vals[1].get_bool(), runtime_error); +} + BOOST_AUTO_TEST_CASE(univalue_set) { UniValue v(UniValue::VSTR, "foo"); @@ -72,13 +114,13 @@ BOOST_AUTO_TEST_CASE(univalue_set) BOOST_CHECK(v.setObject()); BOOST_CHECK(v.isObject()); - BOOST_CHECK_EQUAL(v.count(), 0); + BOOST_CHECK_EQUAL(v.size(), 0); BOOST_CHECK_EQUAL(v.getType(), UniValue::VOBJ); BOOST_CHECK(v.empty()); BOOST_CHECK(v.setArray()); BOOST_CHECK(v.isArray()); - BOOST_CHECK_EQUAL(v.count(), 0); + BOOST_CHECK_EQUAL(v.size(), 0); BOOST_CHECK(v.setStr("zum")); BOOST_CHECK(v.isStr()); @@ -145,7 +187,7 @@ BOOST_AUTO_TEST_CASE(univalue_array) BOOST_CHECK(arr.push_backV(vec)); BOOST_CHECK_EQUAL(arr.empty(), false); - BOOST_CHECK_EQUAL(arr.count(), 5); + BOOST_CHECK_EQUAL(arr.size(), 5); BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023"); BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy"); @@ -157,7 +199,7 @@ BOOST_AUTO_TEST_CASE(univalue_array) arr.clear(); BOOST_CHECK(arr.empty()); - BOOST_CHECK_EQUAL(arr.count(), 0); + BOOST_CHECK_EQUAL(arr.size(), 0); } BOOST_AUTO_TEST_CASE(univalue_object) @@ -197,7 +239,7 @@ BOOST_AUTO_TEST_CASE(univalue_object) BOOST_CHECK(obj.pushKVs(obj2)); BOOST_CHECK_EQUAL(obj.empty(), false); - BOOST_CHECK_EQUAL(obj.count(), 9); + BOOST_CHECK_EQUAL(obj.size(), 9); BOOST_CHECK_EQUAL(obj["age"].getValStr(), "100"); BOOST_CHECK_EQUAL(obj["first"].getValStr(), "John"); @@ -240,11 +282,11 @@ BOOST_AUTO_TEST_CASE(univalue_object) obj.clear(); BOOST_CHECK(obj.empty()); - BOOST_CHECK_EQUAL(obj.count(), 0); + BOOST_CHECK_EQUAL(obj.size(), 0); } static const char *json1 = -"[1.1,{\"key1\":\"str\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]"; +"[1.10000000,{\"key1\":\"str\\u0000\",\"key2\":800,\"key3\":{\"name\":\"martian http://test.com\"}}]"; BOOST_AUTO_TEST_CASE(univalue_readwrite) { @@ -255,21 +297,38 @@ BOOST_AUTO_TEST_CASE(univalue_readwrite) BOOST_CHECK(v.read(strJson1)); BOOST_CHECK(v.isArray()); - BOOST_CHECK_EQUAL(v.count(), 2); + BOOST_CHECK_EQUAL(v.size(), 2); - BOOST_CHECK_EQUAL(v[0].getValStr(), "1.1"); + BOOST_CHECK_EQUAL(v[0].getValStr(), "1.10000000"); UniValue obj = v[1]; BOOST_CHECK(obj.isObject()); - BOOST_CHECK_EQUAL(obj.count(), 3); + BOOST_CHECK_EQUAL(obj.size(), 3); BOOST_CHECK(obj["key1"].isStr()); - BOOST_CHECK_EQUAL(obj["key1"].getValStr(), "str"); + std::string correctValue("str"); + correctValue.push_back('\0'); + BOOST_CHECK_EQUAL(obj["key1"].getValStr(), correctValue); BOOST_CHECK(obj["key2"].isNum()); BOOST_CHECK_EQUAL(obj["key2"].getValStr(), "800"); BOOST_CHECK(obj["key3"].isObject()); BOOST_CHECK_EQUAL(strJson1, v.write()); + + /* Check for (correctly reporting) a parsing error if the initial + JSON construct is followed by more stuff. Note that whitespace + is, of course, exempt. */ + + BOOST_CHECK(v.read(" {}\n ")); + BOOST_CHECK(v.isObject()); + BOOST_CHECK(v.read(" []\n ")); + BOOST_CHECK(v.isArray()); + + BOOST_CHECK(!v.read("@{}")); + BOOST_CHECK(!v.read("{} garbage")); + BOOST_CHECK(!v.read("[]{}")); + BOOST_CHECK(!v.read("{}[]")); + BOOST_CHECK(!v.read("{} 42")); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 3309e2e387..997dc31931 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -146,29 +146,27 @@ BOOST_AUTO_TEST_CASE(util_GetArg) BOOST_AUTO_TEST_CASE(util_FormatMoney) { - BOOST_CHECK_EQUAL(FormatMoney(0, false), "0.00"); - BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789, false), "12345.6789"); - BOOST_CHECK_EQUAL(FormatMoney(COIN, true), "+1.00"); - BOOST_CHECK_EQUAL(FormatMoney(-COIN, false), "-1.00"); - BOOST_CHECK_EQUAL(FormatMoney(-COIN, true), "-1.00"); - - BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000, false), "100000000.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000, false), "10000000.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000, false), "1000000.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN*100000, false), "100000.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN*10000, false), "10000.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN*1000, false), "1000.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN*100, false), "100.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN*10, false), "10.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN, false), "1.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN/10, false), "0.10"); - BOOST_CHECK_EQUAL(FormatMoney(COIN/100, false), "0.01"); - BOOST_CHECK_EQUAL(FormatMoney(COIN/1000, false), "0.001"); - BOOST_CHECK_EQUAL(FormatMoney(COIN/10000, false), "0.0001"); - BOOST_CHECK_EQUAL(FormatMoney(COIN/100000, false), "0.00001"); - BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000, false), "0.000001"); - BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000, false), "0.0000001"); - BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000, false), "0.00000001"); + BOOST_CHECK_EQUAL(FormatMoney(0), "0.00"); + BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789), "12345.6789"); + BOOST_CHECK_EQUAL(FormatMoney(-COIN), "-1.00"); + + BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000), "100000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000), "10000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000), "1000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*100000), "100000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*10000), "10000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*1000), "1000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*100), "100.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*10), "10.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN), "1.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/10), "0.10"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/100), "0.01"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/1000), "0.001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/10000), "0.0001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/100000), "0.00001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000), "0.000001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000), "0.0000001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000), "0.00000001"); } BOOST_AUTO_TEST_CASE(util_ParseMoney) @@ -322,9 +320,16 @@ BOOST_AUTO_TEST_CASE(test_ParseInt32) BOOST_CHECK(ParseInt32("-2147483648", &n) && n == -2147483648); BOOST_CHECK(ParseInt32("-1234", &n) && n == -1234); // Invalid values + BOOST_CHECK(!ParseInt32("", &n)); + BOOST_CHECK(!ParseInt32(" 1", &n)); // no padding inside + BOOST_CHECK(!ParseInt32("1 ", &n)); BOOST_CHECK(!ParseInt32("1a", &n)); BOOST_CHECK(!ParseInt32("aap", &n)); BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex + BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex + const char test_bytes[] = {'1', 0, '1'}; + std::string teststr(test_bytes, sizeof(test_bytes)); + BOOST_CHECK(!ParseInt32(teststr, &n)); // no embedded NULs // Overflow and underflow BOOST_CHECK(!ParseInt32("-2147483649", NULL)); BOOST_CHECK(!ParseInt32("2147483648", NULL)); @@ -332,6 +337,64 @@ BOOST_AUTO_TEST_CASE(test_ParseInt32) BOOST_CHECK(!ParseInt32("32482348723847471234", NULL)); } +BOOST_AUTO_TEST_CASE(test_ParseInt64) +{ + int64_t n; + // Valid values + BOOST_CHECK(ParseInt64("1234", NULL)); + BOOST_CHECK(ParseInt64("0", &n) && n == 0LL); + BOOST_CHECK(ParseInt64("1234", &n) && n == 1234LL); + BOOST_CHECK(ParseInt64("01234", &n) && n == 1234LL); // no octal + BOOST_CHECK(ParseInt64("2147483647", &n) && n == 2147483647LL); + BOOST_CHECK(ParseInt64("-2147483648", &n) && n == -2147483648LL); + BOOST_CHECK(ParseInt64("9223372036854775807", &n) && n == (int64_t)9223372036854775807); + BOOST_CHECK(ParseInt64("-9223372036854775808", &n) && n == (int64_t)-9223372036854775807-1); + BOOST_CHECK(ParseInt64("-1234", &n) && n == -1234LL); + // Invalid values + BOOST_CHECK(!ParseInt64("", &n)); + BOOST_CHECK(!ParseInt64(" 1", &n)); // no padding inside + BOOST_CHECK(!ParseInt64("1 ", &n)); + BOOST_CHECK(!ParseInt64("1a", &n)); + BOOST_CHECK(!ParseInt64("aap", &n)); + BOOST_CHECK(!ParseInt64("0x1", &n)); // no hex + const char test_bytes[] = {'1', 0, '1'}; + std::string teststr(test_bytes, sizeof(test_bytes)); + BOOST_CHECK(!ParseInt64(teststr, &n)); // no embedded NULs + // Overflow and underflow + BOOST_CHECK(!ParseInt64("-9223372036854775809", NULL)); + BOOST_CHECK(!ParseInt64("9223372036854775808", NULL)); + BOOST_CHECK(!ParseInt64("-32482348723847471234", NULL)); + BOOST_CHECK(!ParseInt64("32482348723847471234", NULL)); +} + +BOOST_AUTO_TEST_CASE(test_ParseDouble) +{ + double n; + // Valid values + BOOST_CHECK(ParseDouble("1234", NULL)); + BOOST_CHECK(ParseDouble("0", &n) && n == 0.0); + BOOST_CHECK(ParseDouble("1234", &n) && n == 1234.0); + BOOST_CHECK(ParseDouble("01234", &n) && n == 1234.0); // no octal + BOOST_CHECK(ParseDouble("2147483647", &n) && n == 2147483647.0); + BOOST_CHECK(ParseDouble("-2147483648", &n) && n == -2147483648.0); + BOOST_CHECK(ParseDouble("-1234", &n) && n == -1234.0); + BOOST_CHECK(ParseDouble("1e6", &n) && n == 1e6); + BOOST_CHECK(ParseDouble("-1e6", &n) && n == -1e6); + // Invalid values + BOOST_CHECK(!ParseDouble("", &n)); + BOOST_CHECK(!ParseDouble(" 1", &n)); // no padding inside + BOOST_CHECK(!ParseDouble("1 ", &n)); + BOOST_CHECK(!ParseDouble("1a", &n)); + BOOST_CHECK(!ParseDouble("aap", &n)); + BOOST_CHECK(!ParseDouble("0x1", &n)); // no hex + const char test_bytes[] = {'1', 0, '1'}; + std::string teststr(test_bytes, sizeof(test_bytes)); + BOOST_CHECK(!ParseDouble(teststr, &n)); // no embedded NULs + // Overflow and underflow + BOOST_CHECK(!ParseDouble("-1e10000", NULL)); + BOOST_CHECK(!ParseDouble("1e10000", NULL)); +} + BOOST_AUTO_TEST_CASE(test_FormatParagraph) { BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), ""); @@ -350,9 +413,75 @@ BOOST_AUTO_TEST_CASE(test_FormatSubVersion) comments.push_back(std::string("comment1")); std::vector<std::string> comments2; comments2.push_back(std::string("comment1")); - comments2.push_back(std::string("comment2")); + comments2.push_back(SanitizeString(std::string("Comment2; .,_?@-; !\"#$%&'()*+/<=>[]\\^`{|}~"), SAFE_CHARS_UA_COMMENT)); // Semicolon is discouraged but not forbidden by BIP-0014 BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, std::vector<std::string>()),std::string("/Test:0.9.99/")); BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),std::string("/Test:0.9.99(comment1)/")); - BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:0.9.99(comment1; comment2)/")); + BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:0.9.99(comment1; Comment2; .,_?@-; )/")); } + +BOOST_AUTO_TEST_CASE(test_ParseFixedPoint) +{ + int64_t amount = 0; + BOOST_CHECK(ParseFixedPoint("0", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 0LL); + BOOST_CHECK(ParseFixedPoint("1", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 100000000LL); + BOOST_CHECK(ParseFixedPoint("0.0", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 0LL); + BOOST_CHECK(ParseFixedPoint("-0.1", 8, &amount)); + BOOST_CHECK_EQUAL(amount, -10000000LL); + BOOST_CHECK(ParseFixedPoint("1.1", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 110000000LL); + BOOST_CHECK(ParseFixedPoint("1.10000000000000000", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 110000000LL); + BOOST_CHECK(ParseFixedPoint("1.1e1", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 1100000000LL); + BOOST_CHECK(ParseFixedPoint("1.1e-1", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 11000000LL); + BOOST_CHECK(ParseFixedPoint("1000", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 100000000000LL); + BOOST_CHECK(ParseFixedPoint("-1000", 8, &amount)); + BOOST_CHECK_EQUAL(amount, -100000000000LL); + BOOST_CHECK(ParseFixedPoint("0.00000001", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 1LL); + BOOST_CHECK(ParseFixedPoint("0.0000000100000000", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 1LL); + BOOST_CHECK(ParseFixedPoint("-0.00000001", 8, &amount)); + BOOST_CHECK_EQUAL(amount, -1LL); + BOOST_CHECK(ParseFixedPoint("1000000000.00000001", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 100000000000000001LL); + BOOST_CHECK(ParseFixedPoint("9999999999.99999999", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 999999999999999999LL); + BOOST_CHECK(ParseFixedPoint("-9999999999.99999999", 8, &amount)); + BOOST_CHECK_EQUAL(amount, -999999999999999999LL); + + BOOST_CHECK(!ParseFixedPoint("", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("a-1000", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-a1000", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-1000a", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-01000", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("00.1", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint(".1", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("--0.1", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("0.000000001", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-0.000000001", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("0.00000001000000001", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-10000000000.00000000", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("10000000000.00000000", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-10000000000.00000001", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("10000000000.00000001", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-10000000000.00000009", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("10000000000.00000009", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-99999999999.99999999", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("99999909999.09999999", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("92233720368.54775807", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("92233720368.54775808", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-92233720368.54775808", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-92233720368.54775809", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("1.1e", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("1.1e-", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("1.", 8, &amount)); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/timedata.cpp b/src/timedata.cpp index c3e9c75f6e..0641009537 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -40,16 +40,20 @@ static int64_t abs64(int64_t n) return (n >= 0 ? n : -n); } +#define BITCOIN_TIMEDATA_MAX_SAMPLES 200 + void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) { LOCK(cs_nTimeOffset); // Ignore duplicates static set<CNetAddr> setKnown; + if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES) + return; if (!setKnown.insert(ip).second) return; // Add data - static CMedianFilter<int64_t> vTimeOffsets(200,0); + static CMedianFilter<int64_t> vTimeOffsets(BITCOIN_TIMEDATA_MAX_SAMPLES, 0); vTimeOffsets.input(nOffsetSample); LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60); @@ -95,9 +99,8 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) if (!fMatch) { fDone = true; - string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly."); + string strMessage = _("Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly."); strMiscWarning = strMessage; - LogPrintf("*** %s\n", strMessage); uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING); } } diff --git a/src/txdb.cpp b/src/txdb.cpp index df9ff8d8c9..21ecd65238 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -5,6 +5,7 @@ #include "txdb.h" +#include "chain.h" #include "chainparams.h" #include "hash.h" #include "main.h" @@ -147,7 +148,10 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } } - stats.nHeight = mapBlockIndex.find(GetBestBlock())->second->nHeight; + { + LOCK(cs_main); + stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight; + } stats.hashSerialized = ss.GetHash(); stats.nTotalAmount = nTotalAmount; return true; diff --git a/src/txdb.h b/src/txdb.h index 86e1c5d831..bef5dc9fd1 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -22,7 +22,7 @@ class uint256; //! -dbcache default (MiB) static const int64_t nDefaultDbCache = 100; //! max. -dbcache in (MiB) -static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 4096 : 1024; +static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 16384 : 1024; //! min. -dbcache in (MiB) static const int64_t nMinDbCache = 4; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index d05e3c6eec..1370cab0c0 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -7,30 +7,29 @@ #include "clientversion.h" #include "consensus/consensus.h" +#include "consensus/validation.h" #include "main.h" +#include "policy/fees.h" #include "streams.h" #include "util.h" #include "utilmoneystr.h" #include "version.h" -#include <boost/circular_buffer.hpp> - using namespace std; -CTxMemPoolEntry::CTxMemPoolEntry(): - nFee(0), nTxSize(0), nModSize(0), nTime(0), dPriority(0.0) -{ - nHeight = MEMPOOL_HEIGHT; -} - CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _dPriority, - unsigned int _nHeight): - tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight) + unsigned int _nHeight, bool poolHasNoInputsOf): + tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight), + hadNoDependencies(poolHasNoInputsOf) { nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); - nModSize = tx.CalculateModifiedSize(nTxSize); + nUsageSize = RecursiveDynamicUsage(tx); + + nCountWithDescendants = 1; + nSizeWithDescendants = nTxSize; + nFeesWithDescendants = nFee; } CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other) @@ -47,346 +46,274 @@ CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const return dResult; } -/** - * Keep track of fee/priority for transactions confirmed within N blocks - */ -class CBlockAverage +// 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<uint256> &setExclude) { -private: - boost::circular_buffer<CFeeRate> feeSamples; - boost::circular_buffer<double> prioritySamples; + // Track the number of entries (outside setExclude) that we'd need to visit + // (will bail out if it exceeds maxDescendantsToVisit) + int nChildrenToVisit = 0; - template<typename T> std::vector<T> buf2vec(boost::circular_buffer<T> buf) const - { - std::vector<T> vec(buf.begin(), buf.end()); - return vec; - } + setEntries stageEntries, setAllDescendants; + stageEntries = GetMemPoolChildren(updateIt); -public: - CBlockAverage() : feeSamples(100), prioritySamples(100) { } - - void RecordFee(const CFeeRate& feeRate) { - feeSamples.push_back(feeRate); - } - - void RecordPriority(double priority) { - prioritySamples.push_back(priority); - } - - size_t FeeSamples() const { return feeSamples.size(); } - size_t GetFeeSamples(std::vector<CFeeRate>& insertInto) const - { - BOOST_FOREACH(const CFeeRate& f, feeSamples) - insertInto.push_back(f); - return feeSamples.size(); - } - size_t PrioritySamples() const { return prioritySamples.size(); } - size_t GetPrioritySamples(std::vector<double>& insertInto) const - { - BOOST_FOREACH(double d, prioritySamples) - insertInto.push_back(d); - return prioritySamples.size(); - } - - /** - * Used as belt-and-suspenders check when reading to detect - * file corruption - */ - static bool AreSane(const CFeeRate fee, const CFeeRate& minRelayFee) - { - if (fee < CFeeRate(0)) - return false; - if (fee.GetFeePerK() > minRelayFee.GetFeePerK() * 10000) + while (!stageEntries.empty()) { + const txiter cit = *stageEntries.begin(); + if (cit->IsDirty()) { + // Don't consider any more children if any descendant is dirty return false; - return true; - } - static bool AreSane(const std::vector<CFeeRate>& vecFee, const CFeeRate& minRelayFee) - { - BOOST_FOREACH(CFeeRate fee, vecFee) - { - if (!AreSane(fee, minRelayFee)) - return false; } - return true; - } - static bool AreSane(const double priority) - { - return priority >= 0; - } - static bool AreSane(const std::vector<double> vecPriority) - { - BOOST_FOREACH(double priority, vecPriority) - { - if (!AreSane(priority)) + setAllDescendants.insert(cit); + stageEntries.erase(cit); + const setEntries &setChildren = GetMemPoolChildren(cit); + BOOST_FOREACH(const txiter childEntry, setChildren) { + cacheMap::iterator cacheIt = cachedDescendants.find(childEntry); + if (cacheIt != cachedDescendants.end()) { + // 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++; + } + } + } 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; + } } - return true; } - - void Write(CAutoFile& fileout) const - { - std::vector<CFeeRate> vecFee = buf2vec(feeSamples); - fileout << vecFee; - std::vector<double> vecPriority = buf2vec(prioritySamples); - fileout << vecPriority; - } - - void Read(CAutoFile& filein, const CFeeRate& minRelayFee) { - std::vector<CFeeRate> vecFee; - filein >> vecFee; - if (AreSane(vecFee, minRelayFee)) - feeSamples.insert(feeSamples.end(), vecFee.begin(), vecFee.end()); - else - throw runtime_error("Corrupt fee value in estimates file."); - std::vector<double> vecPriority; - filein >> vecPriority; - if (AreSane(vecPriority)) - prioritySamples.insert(prioritySamples.end(), vecPriority.begin(), vecPriority.end()); - else - throw runtime_error("Corrupt priority value in estimates file."); - if (feeSamples.size() + prioritySamples.size() > 0) - LogPrint("estimatefee", "Read %d fee samples and %d priority samples\n", - feeSamples.size(), prioritySamples.size()); - } -}; - -class CMinerPolicyEstimator -{ -private: - /** - * Records observed averages transactions that confirmed within one block, two blocks, - * three blocks etc. - */ - std::vector<CBlockAverage> history; - std::vector<CFeeRate> sortedFeeSamples; - std::vector<double> sortedPrioritySamples; - - int nBestSeenHeight; - - /** - * nBlocksAgo is 0 based, i.e. transactions that confirmed in the highest seen block are - * nBlocksAgo == 0, transactions in the block before that are nBlocksAgo == 1 etc. - */ - void seenTxConfirm(const CFeeRate& feeRate, const CFeeRate& minRelayFee, double dPriority, int nBlocksAgo) - { - // Last entry records "everything else". - int nBlocksTruncated = min(nBlocksAgo, (int) history.size() - 1); - assert(nBlocksTruncated >= 0); - - // We need to guess why the transaction was included in a block-- either - // because it is high-priority or because it has sufficient fees. - bool sufficientFee = (feeRate > minRelayFee); - bool sufficientPriority = AllowFree(dPriority); - const char* assignedTo = "unassigned"; - if (sufficientFee && !sufficientPriority && CBlockAverage::AreSane(feeRate, minRelayFee)) - { - history[nBlocksTruncated].RecordFee(feeRate); - assignedTo = "fee"; - } - else if (sufficientPriority && !sufficientFee && CBlockAverage::AreSane(dPriority)) - { - history[nBlocksTruncated].RecordPriority(dPriority); - assignedTo = "priority"; + // setAllDescendants now contains all in-mempool descendants of updateIt. + // Update and add to cached descendant map + int64_t modifySize = 0; + CAmount modifyFee = 0; + int64_t modifyCount = 0; + BOOST_FOREACH(txiter cit, setAllDescendants) { + if (!setExclude.count(cit->GetTx().GetHash())) { + modifySize += cit->GetTxSize(); + modifyFee += cit->GetFee(); + modifyCount++; + cachedDescendants[updateIt].insert(cit); } - else - { - // Neither or both fee and priority sufficient to get confirmed: - // don't know why they got confirmed. - } - LogPrint("estimatefee", "Seen TX confirm: %s: %s fee/%g priority, took %d blocks\n", - assignedTo, feeRate.ToString(), dPriority, nBlocksAgo); - } - -public: - CMinerPolicyEstimator(int nEntries) : nBestSeenHeight(0) - { - history.resize(nEntries); } + mapTx.modify(updateIt, update_descendant_state(modifySize, modifyFee, modifyCount)); + return true; +} - void seenBlock(const std::vector<CTxMemPoolEntry>& entries, int nBlockHeight, const CFeeRate minRelayFee) - { - if (nBlockHeight <= nBestSeenHeight) - { - // Ignore side chains and re-orgs; assuming they are random - // they don't affect the estimate. - // And if an attacker can re-org the chain at will, then - // you've got much bigger problems than "attacker can influence - // transaction fees." - return; +// vHashesToUpdate is the set of transaction hashes from a disconnected block +// 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. +void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashesToUpdate) +{ + LOCK(cs); + // For each entry in vHashesToUpdate, store the set of in-mempool, but not + // in-vHashesToUpdate transactions, so that we don't have to recalculate + // descendants when we come across a previously seen entry. + cacheMap mapMemPoolDescendantsToUpdate; + + // Use a set for lookups into vHashesToUpdate (these entries are already + // accounted for in the state of their ancestors) + std::set<uint256> setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end()); + + // Iterate in reverse, so that whenever we are looking at at a transaction + // we are sure that all in-mempool descendants have already been processed. + // This maximizes the benefit of the descendant cache and guarantees that + // setMemPoolChildren will be updated, an assumption made in + // UpdateForDescendants. + BOOST_REVERSE_FOREACH(const uint256 &hash, vHashesToUpdate) { + // we cache the in-mempool children to avoid duplicate updates + setEntries setChildren; + // calculate children from mapNextTx + txiter it = mapTx.find(hash); + if (it == mapTx.end()) { + continue; } - nBestSeenHeight = nBlockHeight; - - // Fill up the history buckets based on how long transactions took - // to confirm. - std::vector<std::vector<const CTxMemPoolEntry*> > entriesByConfirmations; - entriesByConfirmations.resize(history.size()); - BOOST_FOREACH(const CTxMemPoolEntry& entry, entries) - { - // How many blocks did it take for miners to include this transaction? - int delta = nBlockHeight - entry.GetHeight(); - if (delta <= 0) - { - // Re-org made us lose height, this should only happen if we happen - // to re-org on a difficulty transition point: very rare! - continue; + std::map<COutPoint, CInPoint>::iterator 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(); + txiter childIter = mapTx.find(childHash); + assert(childIter != mapTx.end()); + // We can skip updating entries we've encountered before or that + // are in the block (which are already accounted for). + if (setChildren.insert(childIter).second && !setAlreadyIncluded.count(childHash)) { + UpdateChild(it, childIter, true); + UpdateParent(childIter, it, true); } - if ((delta-1) >= (int)history.size()) - delta = history.size(); // Last bucket is catch-all - entriesByConfirmations.at(delta-1).push_back(&entry); } - for (size_t i = 0; i < entriesByConfirmations.size(); i++) - { - std::vector<const CTxMemPoolEntry*> &e = entriesByConfirmations.at(i); - // Insert at most 10 random entries per bucket, otherwise a single block - // can dominate an estimate: - if (e.size() > 10) { - std::random_shuffle(e.begin(), e.end()); - e.resize(10); - } - BOOST_FOREACH(const CTxMemPoolEntry* entry, e) - { - // Fees are stored and reported as BTC-per-kb: - CFeeRate feeRate(entry->GetFee(), entry->GetTxSize()); - double dPriority = entry->GetPriority(entry->GetHeight()); // Want priority when it went IN - seenTxConfirm(feeRate, minRelayFee, dPriority, i); - } + if (!UpdateForDescendants(it, 100, mapMemPoolDescendantsToUpdate, setAlreadyIncluded)) { + // Mark as dirty if we can't do the calculation. + mapTx.modify(it, set_dirty()); } + } +} - // After new samples are added, we have to clear the sorted lists, - // so they'll be resorted the next time someone asks for an estimate - sortedFeeSamples.clear(); - sortedPrioritySamples.clear(); - - for (size_t i = 0; i < history.size(); i++) { - if (history[i].FeeSamples() + history[i].PrioritySamples() > 0) - LogPrint("estimatefee", "estimates: for confirming within %d blocks based on %d/%d samples, fee=%s, prio=%g\n", - i, - history[i].FeeSamples(), history[i].PrioritySamples(), - estimateFee(i+1).ToString(), estimatePriority(i+1)); +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 */) +{ + setEntries parentHashes; + const CTransaction &tx = entry.GetTx(); + + if (fSearchForParents) { + // Get parents of this transaction that are in the mempool + // GetMemPoolParents() is only valid for entries in the mempool, so we + // iterate mapTx to find parents. + for (unsigned int i = 0; i < tx.vin.size(); i++) { + txiter piter = mapTx.find(tx.vin[i].prevout.hash); + if (piter != mapTx.end()) { + parentHashes.insert(piter); + if (parentHashes.size() + 1 > limitAncestorCount) { + errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount); + return false; + } + } } + } else { + // If we're not searching for parents, we require this to be an + // entry in the mempool already. + txiter it = mapTx.iterator_to(entry); + parentHashes = GetMemPoolParents(it); } - /** - * Can return CFeeRate(0) if we don't have any data for that many blocks back. nBlocksToConfirm is 1 based. - */ - CFeeRate estimateFee(int nBlocksToConfirm) - { - nBlocksToConfirm--; + size_t totalSizeWithAncestors = entry.GetTxSize(); - if (nBlocksToConfirm < 0 || nBlocksToConfirm >= (int)history.size()) - return CFeeRate(0); + while (!parentHashes.empty()) { + txiter stageit = *parentHashes.begin(); - if (sortedFeeSamples.size() == 0) - { - for (size_t i = 0; i < history.size(); i++) - history.at(i).GetFeeSamples(sortedFeeSamples); - std::sort(sortedFeeSamples.begin(), sortedFeeSamples.end(), - std::greater<CFeeRate>()); - } - if (sortedFeeSamples.size() < 11) - { - // Eleven is Gavin's Favorite Number - // ... but we also take a maximum of 10 samples per block so eleven means - // we're getting samples from at least two different blocks - return CFeeRate(0); - } + setAncestors.insert(stageit); + parentHashes.erase(stageit); + totalSizeWithAncestors += stageit->GetTxSize(); - int nBucketSize = history.at(nBlocksToConfirm).FeeSamples(); + if (stageit->GetSizeWithDescendants() + entry.GetTxSize() > limitDescendantSize) { + errString = strprintf("exceeds descendant size limit for tx %s [limit: %u]", stageit->GetTx().GetHash().ToString(), limitDescendantSize); + return false; + } else if (stageit->GetCountWithDescendants() + 1 > limitDescendantCount) { + errString = strprintf("too many descendants for tx %s [limit: %u]", stageit->GetTx().GetHash().ToString(), limitDescendantCount); + return false; + } else if (totalSizeWithAncestors > limitAncestorSize) { + errString = strprintf("exceeds ancestor size limit [limit: %u]", limitAncestorSize); + return false; + } - // Estimates should not increase as number of confirmations goes up, - // but the estimates are noisy because confirmations happen discretely - // in blocks. To smooth out the estimates, use all samples in the history - // and use the nth highest where n is (number of samples in previous bucket + - // half the samples in nBlocksToConfirm bucket): - size_t nPrevSize = 0; - for (int i = 0; i < nBlocksToConfirm; i++) - nPrevSize += history.at(i).FeeSamples(); - size_t index = min(nPrevSize + nBucketSize/2, sortedFeeSamples.size()-1); - return sortedFeeSamples[index]; + const setEntries & setMemPoolParents = GetMemPoolParents(stageit); + BOOST_FOREACH(const txiter &phash, setMemPoolParents) { + // If this is a new ancestor, add it. + if (setAncestors.count(phash) == 0) { + parentHashes.insert(phash); + } + if (parentHashes.size() + setAncestors.size() + 1 > limitAncestorCount) { + errString = strprintf("too many unconfirmed ancestors [limit: %u]", limitAncestorCount); + return false; + } + } } - double estimatePriority(int nBlocksToConfirm) - { - nBlocksToConfirm--; - if (nBlocksToConfirm < 0 || nBlocksToConfirm >= (int)history.size()) - return -1; - - if (sortedPrioritySamples.size() == 0) - { - for (size_t i = 0; i < history.size(); i++) - history.at(i).GetPrioritySamples(sortedPrioritySamples); - std::sort(sortedPrioritySamples.begin(), sortedPrioritySamples.end(), - std::greater<double>()); - } - if (sortedPrioritySamples.size() < 11) - return -1.0; + return true; +} - int nBucketSize = history.at(nBlocksToConfirm).PrioritySamples(); +void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, setEntries &setAncestors) +{ + setEntries parentIters = GetMemPoolParents(it); + // add or remove this tx as a child of each parent + BOOST_FOREACH(txiter piter, parentIters) { + UpdateChild(piter, it, add); + } + const int64_t updateCount = (add ? 1 : -1); + const int64_t updateSize = updateCount * it->GetTxSize(); + const CAmount updateFee = updateCount * it->GetFee(); + BOOST_FOREACH(txiter ancestorIt, setAncestors) { + mapTx.modify(ancestorIt, update_descendant_state(updateSize, updateFee, updateCount)); + } +} - // Estimates should not increase as number of confirmations needed goes up, - // but the estimates are noisy because confirmations happen discretely - // in blocks. To smooth out the estimates, use all samples in the history - // and use the nth highest where n is (number of samples in previous buckets + - // half the samples in nBlocksToConfirm bucket). - size_t nPrevSize = 0; - for (int i = 0; i < nBlocksToConfirm; i++) - nPrevSize += history.at(i).PrioritySamples(); - size_t index = min(nPrevSize + nBucketSize/2, sortedPrioritySamples.size()-1); - return sortedPrioritySamples[index]; +void CTxMemPool::UpdateChildrenForRemoval(txiter it) +{ + const setEntries &setMemPoolChildren = GetMemPoolChildren(it); + BOOST_FOREACH(txiter updateIt, setMemPoolChildren) { + UpdateParent(updateIt, it, false); } +} - void Write(CAutoFile& fileout) const - { - fileout << nBestSeenHeight; - fileout << (uint32_t)history.size(); - BOOST_FOREACH(const CBlockAverage& entry, history) - { - entry.Write(fileout); - } +void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove) +{ + // For each entry, walk back all ancestors and decrement size associated with this + // transaction + const uint64_t nNoLimit = std::numeric_limits<uint64_t>::max(); + BOOST_FOREACH(txiter removeIt, entriesToRemove) { + setEntries setAncestors; + const CTxMemPoolEntry &entry = *removeIt; + std::string dummy; + // Since this is a tx that is already in the mempool, we can call CMPA + // with fSearchForParents = false. If the mempool is in a consistent + // state, then using true or false should both be correct, though false + // should be a bit faster. + // However, if we happen to be in the middle of processing a reorg, then + // the mempool can be in an inconsistent state. In this case, the set + // of ancestors reachable via mapLinks will be the same as the set of + // ancestors whose packages include this transaction, because when we + // add a new transaction to the mempool in addUnchecked(), we assume it + // has no children, and in the case of a reorg where that assumption is + // false, the in-mempool children aren't linked to the in-block tx's + // until UpdateTransactionsFromBlock() is called. + // So if we're being called during a reorg, ie before + // UpdateTransactionsFromBlock() has been called, then mapLinks[] will + // differ from the set of mempool parents we'd calculate by searching, + // and it's important that we use the mapLinks[] notion of ancestor + // 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!) + UpdateAncestorsOf(false, removeIt, setAncestors); + } + // After updating all the ancestor sizes, we can now sever the link between each + // transaction being removed and any mempool children (ie, update setMemPoolParents + // for each direct child of a transaction being removed). + BOOST_FOREACH(txiter removeIt, entriesToRemove) { + UpdateChildrenForRemoval(removeIt); } +} - void Read(CAutoFile& filein, const CFeeRate& minRelayFee) - { - int nFileBestSeenHeight; - filein >> nFileBestSeenHeight; - uint32_t numEntries; - filein >> numEntries; - if (numEntries <= 0 || numEntries > 10000) - throw runtime_error("Corrupt estimates file. Must have between 1 and 10k entries."); - - std::vector<CBlockAverage> fileHistory; - - for (size_t i = 0; i < numEntries; i++) - { - CBlockAverage entry; - entry.Read(filein, minRelayFee); - fileHistory.push_back(entry); - } +void CTxMemPoolEntry::SetDirty() +{ + nCountWithDescendants = 0; + nSizeWithDescendants = nTxSize; + nFeesWithDescendants = nFee; +} - // Now that we've processed the entire fee estimate data file and not - // thrown any errors, we can copy it to our history - nBestSeenHeight = nFileBestSeenHeight; - history = fileHistory; - assert(history.size() > 0); +void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount) +{ + if (!IsDirty()) { + nSizeWithDescendants += modifySize; + assert(int64_t(nSizeWithDescendants) > 0); + nFeesWithDescendants += modifyFee; + assert(nFeesWithDescendants >= 0); + nCountWithDescendants += modifyCount; + assert(int64_t(nCountWithDescendants) > 0); } -}; - +} CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) : - nTransactionsUpdated(0), - minRelayFee(_minRelayFee) + nTransactionsUpdated(0) { // Sanity checks off by default for performance, because otherwise // accepting transactions becomes O(N^2) where N is the number // of transactions in the pool fSanityCheck = false; - // 25 blocks is a compromise between using a lot of disk/memory and - // trying to give accurate estimates to people who might be willing - // to wait a day or two to save a fraction of a penny in fees. - // Confirmation times for very-low-fee transactions that take more - // than an hour or three to confirm are highly variable. - minerPolicyEstimator = new CMinerPolicyEstimator(25); + minerPolicyEstimator = new CBlockPolicyEstimator(_minRelayFee); } CTxMemPool::~CTxMemPool() @@ -419,33 +346,103 @@ void CTxMemPool::AddTransactionsUpdated(unsigned int n) nTransactionsUpdated += n; } - -bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry) +bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate) { // Add to memory pool without checking anything. // Used by main.cpp AcceptToMemoryPool(), which DOES do // all the appropriate checks. LOCK(cs); - { - mapTx[hash] = entry; - const CTransaction& tx = mapTx[hash].GetTx(); - for (unsigned int i = 0; i < tx.vin.size(); i++) - mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i); - nTransactionsUpdated++; - totalTxSize += entry.GetTxSize(); + indexed_transaction_set::iterator newit = mapTx.insert(entry).first; + mapLinks.insert(make_pair(newit, TxLinks())); + + // Update cachedInnerUsage to include contained transaction's usage. + // (When we update the entry for in-mempool parents, memory usage will be + // further updated.) + cachedInnerUsage += entry.DynamicMemoryUsage(); + + const CTransaction& tx = newit->GetTx(); + std::set<uint256> setParentTransactions; + for (unsigned int i = 0; i < tx.vin.size(); i++) { + mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i); + setParentTransactions.insert(tx.vin[i].prevout.hash); + } + // Don't bother worrying about child transactions of this one. + // Normal case of a new transaction arriving is that there can't be any + // children, because such children would be orphans. + // An exception to that is if a transaction enters that used to be in a block. + // In that case, our disconnect block logic will call UpdateTransactionsFromBlock + // to clean up the mess we're leaving here. + + // Update ancestors with information about this tx + BOOST_FOREACH (const uint256 &phash, setParentTransactions) { + txiter pit = mapTx.find(phash); + if (pit != mapTx.end()) { + UpdateParent(newit, pit, true); + } } + UpdateAncestorsOf(true, newit, setAncestors); + + nTransactionsUpdated++; + totalTxSize += entry.GetTxSize(); + minerPolicyEstimator->processTransaction(entry, fCurrentEstimate); + return true; } +void CTxMemPool::removeUnchecked(txiter it) +{ + const uint256 hash = it->GetTx().GetHash(); + BOOST_FOREACH(const CTxIn& txin, it->GetTx().vin) + mapNextTx.erase(txin.prevout); + + totalTxSize -= it->GetTxSize(); + cachedInnerUsage -= it->DynamicMemoryUsage(); + cachedInnerUsage -= memusage::DynamicUsage(mapLinks[it].parents) + memusage::DynamicUsage(mapLinks[it].children); + mapLinks.erase(it); + mapTx.erase(it); + nTransactionsUpdated++; + minerPolicyEstimator->removeTx(hash); +} + +// Calculates descendants of entry that are not already in setDescendants, and adds to +// setDescendants. Assumes entryit is already a tx in the mempool and setMemPoolChildren +// is correct for tx and all descendants. +// Also assumes that if an entry is in setDescendants already, then all +// in-mempool descendants of it are already in setDescendants as well, so that we +// can save time by not iterating over those entries. +void CTxMemPool::CalculateDescendants(txiter entryit, setEntries &setDescendants) +{ + setEntries stage; + if (setDescendants.count(entryit) == 0) { + stage.insert(entryit); + } + // Traverse down the children of entry, only adding children that are not + // accounted for in setDescendants already (because those children have either + // already been walked, or will be walked in this iteration). + while (!stage.empty()) { + txiter it = *stage.begin(); + setDescendants.insert(it); + stage.erase(it); + + const setEntries &setChildren = GetMemPoolChildren(it); + BOOST_FOREACH(const txiter &childiter, setChildren) { + if (!setDescendants.count(childiter)) { + stage.insert(childiter); + } + } + } +} void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& removed, bool fRecursive) { // Remove transaction from memory pool { LOCK(cs); - std::deque<uint256> txToRemove; - txToRemove.push_back(origTx.GetHash()); - if (fRecursive && !mapTx.count(origTx.GetHash())) { + setEntries txToRemove; + 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 // 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 @@ -454,32 +451,23 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& rem std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(origTx.GetHash(), i)); if (it == mapNextTx.end()) continue; - txToRemove.push_back(it->second.ptx->GetHash()); + txiter nextit = mapTx.find(it->second.ptx->GetHash()); + assert(nextit != mapTx.end()); + txToRemove.insert(nextit); } } - while (!txToRemove.empty()) - { - uint256 hash = txToRemove.front(); - txToRemove.pop_front(); - if (!mapTx.count(hash)) - continue; - const CTransaction& tx = mapTx[hash].GetTx(); - if (fRecursive) { - for (unsigned int i = 0; i < tx.vout.size(); i++) { - std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(hash, i)); - if (it == mapNextTx.end()) - continue; - txToRemove.push_back(it->second.ptx->GetHash()); - } + setEntries setAllRemoves; + if (fRecursive) { + BOOST_FOREACH(txiter it, txToRemove) { + CalculateDescendants(it, setAllRemoves); } - BOOST_FOREACH(const CTxIn& txin, tx.vin) - mapNextTx.erase(txin.prevout); - - removed.push_back(tx); - totalTxSize -= mapTx[hash].GetTxSize(); - mapTx.erase(hash); - nTransactionsUpdated++; + } else { + setAllRemoves.swap(txToRemove); } + BOOST_FOREACH(txiter it, setAllRemoves) { + removed.push_back(it->GetTx()); + } + RemoveStaged(setAllRemoves); } } @@ -488,15 +476,15 @@ void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned in // Remove transactions spending a coinbase which are now immature LOCK(cs); list<CTransaction> transactionsToRemove; - for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { - const CTransaction& tx = it->second.GetTx(); + for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { + const CTransaction& tx = it->GetTx(); BOOST_FOREACH(const CTxIn& txin, tx.vin) { - std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash); + indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); if (it2 != mapTx.end()) continue; const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); if (fSanityCheck) assert(coins); - if (!coins || (coins->IsCoinBase() && nMemPoolHeight - coins->nHeight < COINBASE_MATURITY)) { + if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) { transactionsToRemove.push_back(tx); break; } @@ -529,17 +517,18 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction> * Called when a block is connected. Removes from mempool and updates the miner fee estimator. */ void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight, - std::list<CTransaction>& conflicts) + std::list<CTransaction>& conflicts, bool fCurrentEstimate) { LOCK(cs); std::vector<CTxMemPoolEntry> entries; BOOST_FOREACH(const CTransaction& tx, vtx) { uint256 hash = tx.GetHash(); - if (mapTx.count(hash)) - entries.push_back(mapTx[hash]); + + indexed_transaction_set::iterator i = mapTx.find(hash); + if (i != mapTx.end()) + entries.push_back(*i); } - minerPolicyEstimator->seenBlock(entries, nBlockHeight, minRelayFee); BOOST_FOREACH(const CTransaction& tx, vtx) { std::list<CTransaction> dummy; @@ -547,15 +536,18 @@ void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned i removeConflicts(tx, conflicts); ClearPrioritisation(tx.GetHash()); } + // After the txs in the new block have been removed from the mempool, update policy estimates + minerPolicyEstimator->processBlock(nBlockHeight, entries, fCurrentEstimate); } - void CTxMemPool::clear() { LOCK(cs); + mapLinks.clear(); mapTx.clear(); mapNextTx.clear(); totalTxSize = 0; + cachedInnerUsage = 0; ++nTransactionsUpdated; } @@ -567,23 +559,31 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const LogPrint("mempool", "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size()); uint64_t checkTotal = 0; + uint64_t innerUsage = 0; CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(pcoins)); LOCK(cs); list<const CTxMemPoolEntry*> waitingOnDependants; - for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { + for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { unsigned int i = 0; - checkTotal += it->second.GetTxSize(); - const CTransaction& tx = it->second.GetTx(); + checkTotal += it->GetTxSize(); + innerUsage += it->DynamicMemoryUsage(); + const CTransaction& tx = it->GetTx(); + txlinksMap::const_iterator linksiter = mapLinks.find(it); + assert(linksiter != mapLinks.end()); + const TxLinks &links = linksiter->second; + innerUsage += memusage::DynamicUsage(links.parents) + memusage::DynamicUsage(links.children); bool fDependsWait = false; + setEntries setParentCheck; BOOST_FOREACH(const CTxIn &txin, tx.vin) { // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's. - std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash); + indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); if (it2 != mapTx.end()) { - const CTransaction& tx2 = it2->second.GetTx(); + const CTransaction& tx2 = it2->GetTx(); assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull()); fDependsWait = true; + setParentCheck.insert(it2); } else { const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash); assert(coins && coins->IsAvailable(txin.prevout.n)); @@ -595,8 +595,35 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const assert(it3->second.n == i); i++; } + assert(setParentCheck == GetMemPoolParents(it)); + // Check children against mapNextTx + CTxMemPool::setEntries setChildrenCheck; + std::map<COutPoint, CInPoint>::const_iterator iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0)); + int64_t childSizes = 0; + CAmount childFees = 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(); + } + } + assert(setChildrenCheck == GetMemPoolChildren(it)); + // Also check to make sure size/fees 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->GetFeesWithDescendants() >= 0); + if (fDependsWait) - waitingOnDependants.push_back(&it->second); + waitingOnDependants.push_back(&(*it)); else { CValidationState state; assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL)); @@ -620,8 +647,8 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const } for (std::map<COutPoint, CInPoint>::const_iterator it = mapNextTx.begin(); it != mapNextTx.end(); it++) { uint256 hash = it->second.ptx->GetHash(); - map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(hash); - const CTransaction& tx = it2->second.GetTx(); + 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); @@ -629,6 +656,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const } assert(totalTxSize == checkTotal); + assert(innerUsage == cachedInnerUsage); } void CTxMemPool::queryHashes(vector<uint256>& vtxid) @@ -637,16 +665,16 @@ void CTxMemPool::queryHashes(vector<uint256>& vtxid) LOCK(cs); vtxid.reserve(mapTx.size()); - for (map<uint256, CTxMemPoolEntry>::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) - vtxid.push_back((*mi).first); + for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) + vtxid.push_back(mi->GetTx().GetHash()); } bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const { LOCK(cs); - map<uint256, CTxMemPoolEntry>::const_iterator i = mapTx.find(hash); + indexed_transaction_set::const_iterator i = mapTx.find(hash); if (i == mapTx.end()) return false; - result = i->second.GetTx(); + result = i->GetTx(); return true; } @@ -666,12 +694,12 @@ CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const { try { LOCK(cs); - fileout << 99900; // version required to read: 0.9.99 or later + fileout << 109900; // version required to read: 0.10.99 or later fileout << CLIENT_VERSION; // version that wrote the file minerPolicyEstimator->Write(fileout); } catch (const std::exception&) { - LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)"); + LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)\n"); return false; } return true; @@ -687,10 +715,10 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein) return error("CTxMemPool::ReadFeeEstimates(): up-version (%d) fee estimate file", nVersionRequired); LOCK(cs); - minerPolicyEstimator->Read(filein, minRelayFee); + minerPolicyEstimator->Read(filein); } catch (const std::exception&) { - LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)"); + LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)\n"); return false; } return true; @@ -724,6 +752,13 @@ void CTxMemPool::ClearPrioritisation(const uint256 hash) mapDeltas.erase(hash); } +bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const +{ + for (unsigned int i = 0; i < tx.vin.size(); i++) + if (exists(tx.vin[i].prevout.hash)) + return false; + return true; +} CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { } @@ -742,3 +777,63 @@ bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const { bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const { return mempool.exists(txid) || base->HaveCoins(txid); } + +size_t CTxMemPool::DynamicMemoryUsage() const { + LOCK(cs); + // Estimate the overhead of mapTx to be 9 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented. + return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 9 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + cachedInnerUsage; +} + +void CTxMemPool::RemoveStaged(setEntries &stage) { + AssertLockHeld(cs); + UpdateForRemoveFromMempool(stage); + BOOST_FOREACH(const txiter& it, stage) { + removeUnchecked(it); + } +} + +bool CTxMemPool::addUnchecked(const uint256&hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate) +{ + LOCK(cs); + setEntries setAncestors; + uint64_t nNoLimit = std::numeric_limits<uint64_t>::max(); + std::string dummy; + CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy); + return addUnchecked(hash, entry, setAncestors, fCurrentEstimate); +} + +void CTxMemPool::UpdateChild(txiter entry, txiter child, bool add) +{ + setEntries s; + if (add && mapLinks[entry].children.insert(child).second) { + cachedInnerUsage += memusage::IncrementalDynamicUsage(s); + } else if (!add && mapLinks[entry].children.erase(child)) { + cachedInnerUsage -= memusage::IncrementalDynamicUsage(s); + } +} + +void CTxMemPool::UpdateParent(txiter entry, txiter parent, bool add) +{ + setEntries s; + if (add && mapLinks[entry].parents.insert(parent).second) { + cachedInnerUsage += memusage::IncrementalDynamicUsage(s); + } else if (!add && mapLinks[entry].parents.erase(parent)) { + cachedInnerUsage -= memusage::IncrementalDynamicUsage(s); + } +} + +const CTxMemPool::setEntries & CTxMemPool::GetMemPoolParents(txiter entry) const +{ + assert (entry != mapTx.end()); + txlinksMap::const_iterator it = mapLinks.find(entry); + assert(it != mapLinks.end()); + return it->second.parents; +} + +const CTxMemPool::setEntries & CTxMemPool::GetMemPoolChildren(txiter entry) const +{ + assert (entry != mapTx.end()); + txlinksMap::const_iterator it = mapLinks.find(entry); + assert(it != mapLinks.end()); + return it->second.children; +} diff --git a/src/txmempool.h b/src/txmempool.h index 0732af67e6..c0eef0dd22 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -7,12 +7,17 @@ #define BITCOIN_TXMEMPOOL_H #include <list> +#include <set> #include "amount.h" #include "coins.h" #include "primitives/transaction.h" #include "sync.h" +#undef foreach +#include "boost/multi_index_container.hpp" +#include "boost/multi_index/ordered_index.hpp" + class CAutoFile; inline double AllowFreeThreshold() @@ -30,9 +35,25 @@ 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; -/** - * CTxMemPool stores these: +class CTxMemPool; + +/** \class CTxMemPoolEntry + * + * CTxMemPoolEntry stores data about the correponding transaction, as well + * as data about all in-mempool transactions that depend on the transaction + * ("descendant" transactions). + * + * When a new entry is added to the mempool, we update the descendant state + * (nCountWithDescendants, nSizeWithDescendants, and nFeesWithDescendants) 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 + * amount of work we're willing to do to avoid consuming too much CPU.) + * */ + class CTxMemPoolEntry { private: @@ -40,14 +61,24 @@ private: 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 dPriority; //! Priority when entering the mempool unsigned int nHeight; //! Chain height when entering the mempool + bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool + + // 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 + // correct. + uint64_t nCountWithDescendants; //! number of descendant transactions + uint64_t nSizeWithDescendants; //! ... and size + CAmount nFeesWithDescendants; //! ... and total fees (all including us) public: CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, - int64_t _nTime, double _dPriority, unsigned int _nHeight); - CTxMemPoolEntry(); + int64_t _nTime, double _dPriority, unsigned int _nHeight, bool poolHasNoInputsOf = false); CTxMemPoolEntry(const CTxMemPoolEntry& other); const CTransaction& GetTx() const { return this->tx; } @@ -56,9 +87,103 @@ public: size_t GetTxSize() const { return nTxSize; } int64_t GetTime() const { return nTime; } unsigned int GetHeight() const { return nHeight; } + bool WasClearAtEntry() const { return hadNoDependencies; } + 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); + + /** 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 GetFeesWithDescendants() const { return nFeesWithDescendants; } +}; + +// Helpers for modifying CTxMemPool::mapTx, which is a boost multi_index. +struct update_descendant_state +{ + update_descendant_state(int64_t _modifySize, CAmount _modifyFee, int64_t _modifyCount) : + modifySize(_modifySize), modifyFee(_modifyFee), modifyCount(_modifyCount) + {} + + void operator() (CTxMemPoolEntry &e) + { e.UpdateState(modifySize, modifyFee, modifyCount); } + + private: + int64_t modifySize; + CAmount modifyFee; + int64_t modifyCount; +}; + +struct set_dirty +{ + void operator() (CTxMemPoolEntry &e) + { e.SetDirty(); } }; -class CMinerPolicyEstimator; +// extracts a TxMemPoolEntry's transaction hash +struct mempoolentry_txid +{ + typedef uint256 result_type; + result_type operator() (const CTxMemPoolEntry &entry) const + { + return entry.GetTx().GetHash(); + } +}; + +/** \class CompareTxMemPoolEntryByFee + * + * Sort an entry by max(feerate of entry's tx, feerate with all descendants). + */ +class CompareTxMemPoolEntryByFee +{ +public: + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + { + bool fUseADescendants = UseDescendantFeeRate(a); + bool fUseBDescendants = UseDescendantFeeRate(b); + + double aFees = fUseADescendants ? a.GetFeesWithDescendants() : a.GetFee(); + double aSize = fUseADescendants ? a.GetSizeWithDescendants() : a.GetTxSize(); + + double bFees = fUseBDescendants ? b.GetFeesWithDescendants() : b.GetFee(); + 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; + + if (f1 == f2) { + return a.GetTime() < b.GetTime(); + } + return f1 > f2; + } + + // Calculate which feerate to use for an entry (avoiding division). + bool UseDescendantFeeRate(const CTxMemPoolEntry &a) + { + double f1 = (double)a.GetFee() * a.GetSizeWithDescendants(); + double f2 = (double)a.GetFeesWithDescendants() * a.GetTxSize(); + return f2 > f1; + } +}; + +class CompareTxMemPoolEntryByEntryTime +{ +public: + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + { + return a.GetTime() < b.GetTime(); + } +}; + +class CBlockPolicyEstimator; /** An inpoint - a combination of a transaction and an index n into its vin */ class CInPoint @@ -71,6 +196,7 @@ public: 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; } }; /** @@ -82,20 +208,123 @@ public: * are added to the pool: if a new transaction double-spends * an input of a transaction in the pool, it is dropped, * as are non-standard transactions. + * + * CTxMemPool::mapTx, and CTxMemPoolEntry bookkeeping: + * + * mapTx is a boost::multi_index that sorts the mempool on 2 criteria: + * - transaction hash + * - feerate [we use max(feerate of tx, feerate of tx with all descendants)] + * + * Note: the term "descendant" refers to in-mempool transactions that depend on + * this one, while "ancestor" refers to in-mempool transactions that a given + * transaction depends on. + * + * In order for the feerate sort to remain correct, we must update transactions + * in the mempool when new descendants arrive. To facilitate this, we track + * the set of in-mempool direct parents and direct children in mapLinks. Within + * each CTxMemPoolEntry, we track the size and fees of all descendants. + * + * Usually when a new transaction is added to the mempool, it has no in-mempool + * children (because any such children would be an orphan). So in + * addUnchecked(), we: + * - update a new entry's setMemPoolParents to include all in-mempool parents + * - update the new entry's direct parents to include the new tx as a child + * - update all ancestors of the transaction to include the new tx's size/fee + * + * When a transaction is removed from the mempool, we must: + * - update all in-mempool parents to not track the tx in setMemPoolChildren + * - update all ancestors to not include the tx's size/fees in descendant state + * - update all in-mempool children to not include it as a parent + * + * These happen in UpdateForRemoveFromMempool(). (Note that when removing a + * transaction along with its descendants, we must calculate that set of + * transactions to be removed before doing the removal, or else the mempool can + * be in an inconsistent state where it's impossible to walk the ancestors of + * a transaction.) + * + * In the event of a reorg, the assumption that a newly added tx has no + * in-mempool children is false. In particular, the mempool is in an + * inconsistent state while new transactions are being added, because there may + * be descendant transactions of a tx coming from a disconnected block that are + * unreachable from just looking at transactions in the mempool (the linking + * transactions may also be in the disconnected block, waiting to be added). + * Because of this, there's not much benefit in trying to search for in-mempool + * children in addUnchecked(). Instead, in the special case of transactions + * being added from a disconnected block, we require the caller to clean up the + * state, to account for in-mempool, out-of-block descendants for all the + * in-block transactions by calling UpdateTransactionsFromBlock(). Note that + * until this is called, the mempool state is not consistent, and in particular + * mapLinks may not be correct (and therefore functions like + * CalculateMemPoolAncestors() and CalculateDescendants() that rely + * on them to walk the mempool are not generally safe to use). + * + * Computational limits: + * + * Updating all in-mempool ancestors of a newly added transaction can be slow, + * if no bound exists on how many in-mempool ancestors there may be. + * CalculateMemPoolAncestors() takes configurable limits that are designed to + * prevent these calculations from being too CPU intensive. + * + * Adding transactions from a disconnected block can be very time consuming, + * because we don't have a way to limit the number of in-mempool descendants. + * To bound CPU processing, we limit the amount of work we're willing to do + * to properly update the descendant information for a tx being added from + * a disconnected block. If we would exceed the limit, then we instead mark + * the entry as "dirty", and set the feerate for sorting purposes to be equal + * the feerate of the transaction without any descendants. + * */ class CTxMemPool { private: bool fSanityCheck; //! Normally false, true if -checkmempool or -regtest unsigned int nTransactionsUpdated; - CMinerPolicyEstimator* minerPolicyEstimator; + CBlockPolicyEstimator* minerPolicyEstimator; - CFeeRate minRelayFee; //! Passed to constructor to avoid dependency on main 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) public: + typedef boost::multi_index_container< + CTxMemPoolEntry, + boost::multi_index::indexed_by< + // sorted by txid + boost::multi_index::ordered_unique<mempoolentry_txid>, + // sorted by fee rate + boost::multi_index::ordered_non_unique< + boost::multi_index::identity<CTxMemPoolEntry>, + CompareTxMemPoolEntryByFee + > + > + > indexed_transaction_set; + mutable CCriticalSection cs; - std::map<uint256, CTxMemPoolEntry> mapTx; + indexed_transaction_set mapTx; + typedef indexed_transaction_set::nth_index<0>::type::iterator txiter; + struct CompareIteratorByHash { + bool operator()(const txiter &a, const txiter &b) const { + return a->GetTx().GetHash() < b->GetTx().GetHash(); + } + }; + typedef std::set<txiter, CompareIteratorByHash> setEntries; + +private: + typedef std::map<txiter, setEntries, CompareIteratorByHash> cacheMap; + + struct TxLinks { + setEntries parents; + setEntries children; + }; + + typedef std::map<txiter, TxLinks, CompareIteratorByHash> txlinksMap; + txlinksMap mapLinks; + + const setEntries & GetMemPoolParents(txiter entry) const; + const setEntries & GetMemPoolChildren(txiter entry) const; + void UpdateParent(txiter entry, txiter parent, bool add); + void UpdateChild(txiter entry, txiter child, bool add); + +public: std::map<COutPoint, CInPoint> mapNextTx; std::map<uint256, std::pair<double, CAmount> > mapDeltas; @@ -111,35 +340,76 @@ public: void check(const CCoinsViewCache *pcoins) const; void setSanityCheck(bool _fSanityCheck) { fSanityCheck = _fSanityCheck; } - bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry); + // addUnchecked must updated state for all ancestors of a given transaction, + // to track size/count of descendant transactions. First version of + // addUnchecked can be used to have it call CalculateMemPoolAncestors(), and + // then invoke the second version. + 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<CTransaction>& removed, bool fRecursive = false); void removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight); void removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed); void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight, - std::list<CTransaction>& conflicts); + std::list<CTransaction>& conflicts, bool fCurrentEstimate = true); void clear(); void queryHashes(std::vector<uint256>& vtxid); void pruneSpent(const uint256& hash, CCoins &coins); unsigned int GetTransactionsUpdated() const; void AddTransactionsUpdated(unsigned int n); + /** + * Check that none of this transactions inputs are in the mempool, and thus + * the tx is not dependent on other mempool transactions to be included in a block. + */ + bool HasNoInputsOf(const CTransaction& tx) const; /** Affect CreateNewBlock prioritisation of transactions */ void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, const CAmount& nFeeDelta); void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta); void ClearPrioritisation(const uint256 hash); +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); + + /** When adding transactions from a disconnected block back to the mempool, + * new mempool entries may have children in the mempool (which is generally + * not the case when otherwise adding transactions). + * UpdateTransactionsFromBlock() will find child transactions and update the + * descendant state for each transaction in hashesToUpdate (excluding any + * child transactions present in hashesToUpdate, which are already accounted + * for). Note: hashesToUpdate should be the set of transactions from the + * disconnected block that have been accepted back into the mempool. + */ + void UpdateTransactionsFromBlock(const std::vector<uint256> &hashesToUpdate); + + /** Try to calculate all in-mempool ancestors of entry. + * (these are all calculated including the tx itself) + * limitAncestorCount = max number of ancestors + * limitAncestorSize = max size of ancestors + * limitDescendantCount = max number of descendants any ancestor can have + * limitDescendantSize = max size of descendants any ancestor can have + * errString = populated with error reason if any limits are hit + * 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); + unsigned long size() { LOCK(cs); return mapTx.size(); } + uint64_t GetTotalTxSize() { LOCK(cs); return totalTxSize; } - bool exists(uint256 hash) + bool exists(uint256 hash) const { LOCK(cs); return (mapTx.count(hash) != 0); @@ -156,6 +426,50 @@ public: /** Write/Read estimates to disk */ bool WriteFeeEstimates(CAutoFile& fileout) const; bool ReadFeeEstimates(CAutoFile& filein); + + size_t DynamicMemoryUsage() const; + +private: + /** UpdateForDescendants is used by UpdateTransactionsFromBlock to update + * the descendants for a single transaction that has been added to the + * mempool but may have child transactions in the mempool, eg during a + * chain reorg. setExclude is the set of descendant transactions in the + * mempool that must not be accounted for (because any descendants in + * setExclude were added to the mempool after the transaction being + * 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, + cacheMap &cachedDescendants, + const std::set<uint256> &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); + /** Sever link between specified transaction and direct children. */ + void UpdateChildrenForRemoval(txiter entry); + /** Populate setDescendants with all in-mempool descendants of hash. + * Assumes that setDescendants includes all in-mempool descendants of anything + * already in it. */ + void CalculateDescendants(txiter it, setEntries &setDescendants); + + /** Before calling removeUnchecked for a given transaction, + * UpdateForRemoveFromMempool must be called on the entire (dependent) set + * of transactions being removed at the same time. We use each + * CTxMemPoolEntry's setMemPoolParents in order to walk ancestors of a + * given transaction that is removed, so we can't remove intermediate + * transactions in a chain before we've updated all the state for the + * removal. + */ + void removeUnchecked(txiter entry); }; /** diff --git a/src/ui_interface.h b/src/ui_interface.h index 32a92a4b81..e402479933 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -95,6 +95,9 @@ public: /** New block has been accepted */ boost::signals2::signal<void (const uint256& hash)> NotifyBlockTip; + + /** Banlist did change. */ + boost::signals2::signal<void (void)> BannedListChanged; }; extern CClientUIInterface uiInterface; diff --git a/src/univalue/gen.cpp b/src/univalue/gen.cpp index abebe88634..5e5a4d4aed 100644 --- a/src/univalue/gen.cpp +++ b/src/univalue/gen.cpp @@ -22,7 +22,6 @@ static void initJsonEscape() { escapes[(int)'"'] = "\\\""; escapes[(int)'\\'] = "\\\\"; - escapes[(int)'/'] = "\\/"; escapes[(int)'\b'] = "\\b"; escapes[(int)'\f'] = "\\f"; escapes[(int)'\n'] = "\\n"; diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp index 4e445a542a..1d49a2cfc9 100644 --- a/src/univalue/univalue.cpp +++ b/src/univalue/univalue.cpp @@ -4,12 +4,17 @@ #include <stdint.h> #include <ctype.h> +#include <iomanip> #include <sstream> +#include <stdexcept> // std::runtime_error + #include "univalue.h" +#include "utilstrencodings.h" // ParseXX + using namespace std; -static const UniValue nullValue; +const UniValue NullUniValue; void UniValue::clear() { @@ -78,9 +83,11 @@ bool UniValue::setFloat(double val) string s; ostringstream oss; - oss << val; + oss << std::setprecision(16) << val; - return setNumStr(oss.str()); + bool ret = setNumStr(oss.str()); + typ = VNUM; + return ret; } bool UniValue::setStr(const string& val_) @@ -175,11 +182,11 @@ bool UniValue::checkObject(const std::map<std::string,UniValue::VType>& t) const UniValue& UniValue::operator[](const std::string& key) const { if (typ != VOBJ) - return nullValue; + return NullUniValue; int index = findKey(key); if (index < 0) - return nullValue; + return NullUniValue; return values[index]; } @@ -187,9 +194,9 @@ const UniValue& UniValue::operator[](const std::string& key) const const UniValue& UniValue::operator[](unsigned int index) const { if (typ != VOBJ && typ != VARR) - return nullValue; + return NullUniValue; if (index >= values.size()) - return nullValue; + return NullUniValue; return values[index]; } @@ -209,3 +216,88 @@ const char *uvTypeName(UniValue::VType t) return NULL; } +const UniValue& find_value( const UniValue& obj, const std::string& name) +{ + for (unsigned int i = 0; i < obj.keys.size(); i++) + { + if( obj.keys[i] == name ) + { + return obj.values[i]; + } + } + + return NullUniValue; +} + +std::vector<std::string> UniValue::getKeys() const +{ + if (typ != VOBJ) + throw std::runtime_error("JSON value is not an object as expected"); + return keys; +} + +std::vector<UniValue> UniValue::getValues() const +{ + if (typ != VOBJ && typ != VARR) + throw std::runtime_error("JSON value is not an object or array as expected"); + return values; +} + +bool UniValue::get_bool() const +{ + if (typ != VBOOL) + throw std::runtime_error("JSON value is not a boolean as expected"); + return getBool(); +} + +std::string UniValue::get_str() const +{ + if (typ != VSTR) + throw std::runtime_error("JSON value is not a string as expected"); + return getValStr(); +} + +int UniValue::get_int() const +{ + if (typ != VNUM) + throw std::runtime_error("JSON value is not an integer as expected"); + int32_t retval; + if (!ParseInt32(getValStr(), &retval)) + throw std::runtime_error("JSON integer out of range"); + return retval; +} + +int64_t UniValue::get_int64() const +{ + if (typ != VNUM) + throw std::runtime_error("JSON value is not an integer as expected"); + int64_t retval; + if (!ParseInt64(getValStr(), &retval)) + throw std::runtime_error("JSON integer out of range"); + return retval; +} + +double UniValue::get_real() const +{ + if (typ != VNUM) + throw std::runtime_error("JSON value is not a number as expected"); + double retval; + if (!ParseDouble(getValStr(), &retval)) + throw std::runtime_error("JSON double out of range"); + return retval; +} + +const UniValue& UniValue::get_obj() const +{ + if (typ != VOBJ) + throw std::runtime_error("JSON value is not an object as expected"); + return *this; +} + +const UniValue& UniValue::get_array() const +{ + if (typ != VARR) + throw std::runtime_error("JSON value is not an array as expected"); + return *this; +} + diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index 88d73b8c64..4742b56f3d 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -11,6 +11,9 @@ #include <map> #include <cassert> +#include <sstream> // .get_int64() +#include <utility> // std::pair + class UniValue { public: enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, }; @@ -26,6 +29,9 @@ public: UniValue(int64_t val_) { setInt(val_); } + UniValue(bool val_) { + setBool(val_); + } UniValue(int val_) { setInt(val_); } @@ -55,10 +61,10 @@ public: bool setObject(); enum VType getType() const { return typ; } - std::string getValStr() const { return val; } + const std::string& getValStr() const { return val; } bool empty() const { return (values.size() == 0); } - size_t count() const { return values.size(); } + size_t size() const { return values.size(); } bool getBool() const { return isTrue(); } bool checkObject(const std::map<std::string,UniValue::VType>& memberTypes); @@ -68,7 +74,7 @@ public: bool isNull() const { return (typ == VNULL); } bool isTrue() const { return (typ == VBOOL) && (val == "1"); } - bool isFalse() const { return (!isTrue()); } + bool isFalse() const { return (typ == VBOOL) && (val != "1"); } bool isBool() const { return (typ == VBOOL); } bool isStr() const { return (typ == VSTR); } bool isNum() const { return (typ == VNUM); } @@ -130,8 +136,91 @@ private: int findKey(const std::string& key) const; void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; + +public: + // Strict type-specific getters, these throw std::runtime_error if the + // value is of unexpected type + std::vector<std::string> getKeys() const; + std::vector<UniValue> getValues() const; + bool get_bool() const; + std::string get_str() const; + int get_int() const; + int64_t get_int64() const; + double get_real() const; + const UniValue& get_obj() const; + const UniValue& get_array() const; + + enum VType type() const { return getType(); } + bool push_back(std::pair<std::string,UniValue> pear) { + return pushKV(pear.first, pear.second); + } + friend const UniValue& find_value( const UniValue& obj, const std::string& name); }; +// +// The following were added for compatibility with json_spirit. +// Most duplicate other methods, and should be removed. +// +static inline std::pair<std::string,UniValue> Pair(const char *cKey, const char *cVal) +{ + std::string key(cKey); + UniValue uVal(cVal); + return std::make_pair(key, uVal); +} + +static inline std::pair<std::string,UniValue> Pair(const char *cKey, std::string strVal) +{ + std::string key(cKey); + UniValue uVal(strVal); + return std::make_pair(key, uVal); +} + +static inline std::pair<std::string,UniValue> Pair(const char *cKey, uint64_t u64Val) +{ + std::string key(cKey); + UniValue uVal(u64Val); + return std::make_pair(key, uVal); +} + +static inline std::pair<std::string,UniValue> Pair(const char *cKey, int64_t i64Val) +{ + std::string key(cKey); + UniValue uVal(i64Val); + return std::make_pair(key, uVal); +} + +static inline std::pair<std::string,UniValue> Pair(const char *cKey, bool iVal) +{ + std::string key(cKey); + UniValue uVal(iVal); + return std::make_pair(key, uVal); +} + +static inline std::pair<std::string,UniValue> Pair(const char *cKey, int iVal) +{ + std::string key(cKey); + UniValue uVal(iVal); + return std::make_pair(key, uVal); +} + +static inline std::pair<std::string,UniValue> Pair(const char *cKey, double dVal) +{ + std::string key(cKey); + UniValue uVal(dVal); + return std::make_pair(key, uVal); +} + +static inline std::pair<std::string,UniValue> Pair(const char *cKey, const UniValue& uVal) +{ + std::string key(cKey); + return std::make_pair(key, uVal); +} + +static inline std::pair<std::string,UniValue> Pair(std::string key, const UniValue& uVal) +{ + return std::make_pair(key, uVal); +} + enum jtokentype { JTOK_ERR = -1, JTOK_NONE = 0, // eof @@ -152,4 +241,8 @@ extern enum jtokentype getJsonToken(std::string& tokenVal, unsigned int& consumed, const char *raw); extern const char *uvTypeName(UniValue::VType t); +extern const UniValue NullUniValue; + +const UniValue& find_value( const UniValue& obj, const std::string& name); + #endif // BITCOIN_UNIVALUE_UNIVALUE_H diff --git a/src/univalue/univalue_escapes.h b/src/univalue/univalue_escapes.h index 0514118285..4133b24ca1 100644 --- a/src/univalue/univalue_escapes.h +++ b/src/univalue/univalue_escapes.h @@ -49,7 +49,7 @@ static const char *escapes[256] = { NULL, NULL, NULL, - "\\/", + NULL, NULL, NULL, NULL, diff --git a/src/univalue/univalue_read.cpp b/src/univalue/univalue_read.cpp index 5cea778996..64591234cb 100644 --- a/src/univalue/univalue_read.cpp +++ b/src/univalue/univalue_read.cpp @@ -188,25 +188,22 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, case 't': valStr += "\t"; break; case 'u': { - char buf[4] = {0,0,0,0}; - char *last = &buf[0]; unsigned int codepoint; if (hatoui(raw + 1, raw + 1 + 4, codepoint) != raw + 1 + 4) return JTOK_ERR; if (codepoint <= 0x7f) - *last = (char)codepoint; + valStr.push_back((char)codepoint); else if (codepoint <= 0x7FF) { - *last++ = (char)(0xC0 | (codepoint >> 6)); - *last = (char)(0x80 | (codepoint & 0x3F)); + valStr.push_back((char)(0xC0 | (codepoint >> 6))); + valStr.push_back((char)(0x80 | (codepoint & 0x3F))); } else if (codepoint <= 0xFFFF) { - *last++ = (char)(0xE0 | (codepoint >> 12)); - *last++ = (char)(0x80 | ((codepoint >> 6) & 0x3F)); - *last = (char)(0x80 | (codepoint & 0x3F)); + valStr.push_back((char)(0xE0 | (codepoint >> 12))); + valStr.push_back((char)(0x80 | ((codepoint >> 6) & 0x3F))); + valStr.push_back((char)(0x80 | (codepoint & 0x3F))); } - valStr += buf; raw += 4; break; } @@ -247,16 +244,16 @@ bool UniValue::read(const char *raw) bool expectColon = false; vector<UniValue*> stack; + string tokenVal; + unsigned int consumed; enum jtokentype tok = JTOK_NONE; enum jtokentype last_tok = JTOK_NONE; - while (1) { + do { last_tok = tok; - string tokenVal; - unsigned int consumed; tok = getJsonToken(tokenVal, consumed, raw); if (tok == JTOK_NONE || tok == JTOK_ERR) - break; + return false; raw += consumed; switch (tok) { @@ -380,9 +377,11 @@ bool UniValue::read(const char *raw) default: return false; } - } + } while (!stack.empty ()); - if (stack.size() != 0) + /* Check that nothing follows the initial construct (parsed above). */ + tok = getJsonToken(tokenVal, consumed, raw); + if (tok != JTOK_NONE) return false; return true; diff --git a/src/univalue/univalue_write.cpp b/src/univalue/univalue_write.cpp index 9a1d364c95..bce3997af7 100644 --- a/src/univalue/univalue_write.cpp +++ b/src/univalue/univalue_write.cpp @@ -3,6 +3,8 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <ctype.h> +#include <iomanip> +#include <sstream> #include <stdio.h> #include "univalue.h" #include "univalue_escapes.h" diff --git a/src/util.cpp b/src/util.cpp index c9e8242d47..f50d25e17a 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -7,11 +7,6 @@ #include "config/bitcoin-config.h" #endif -#if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)) -#include <pthread.h> -#include <pthread_np.h> -#endif - #include "util.h" #include "chainparamsbase.h" @@ -23,6 +18,11 @@ #include <stdarg.h> +#if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)) +#include <pthread.h> +#include <pthread_np.h> +#endif + #ifndef WIN32 // for posix_fallocate #ifdef __linux__ @@ -83,6 +83,7 @@ #include <boost/thread.hpp> #include <openssl/crypto.h> #include <openssl/rand.h> +#include <openssl/conf.h> // Work around clang compilation problem in Boost 1.46: // /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup @@ -113,7 +114,7 @@ CTranslationInterface translationInterface; /** Init OpenSSL library multithreading support */ static CCriticalSection** ppmutexOpenSSL; -void locking_callback(int mode, int i, const char* file, int line) +void locking_callback(int mode, int i, const char* file, int line) NO_THREAD_SAFETY_ANALYSIS { if (mode & CRYPTO_LOCK) { ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]); @@ -134,6 +135,13 @@ public: ppmutexOpenSSL[i] = new CCriticalSection(); CRYPTO_set_locking_callback(locking_callback); + // OpenSSL can optionally load a config file which lists optional loadable modules and engines. + // We don't use them so we don't require the config. However some of our libs may call functions + // which attempt to load the config file, possibly resulting in an exit() or crash if it is missing + // or corrupt. Explicitly tell OpenSSL not to try to load the file. The result for our libs will be + // that the config appears to have been loaded and there are no modules/engines available. + OPENSSL_no_config(); + #ifdef WIN32 // Seed OpenSSL PRNG with current contents of the screen RAND_screen(); @@ -167,23 +175,51 @@ instance_of_cinit; */ static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT; + /** - * We use boost::call_once() to make sure these are initialized - * in a thread-safe manner the first time called: + * We use boost::call_once() to make sure mutexDebugLog and + * vMsgsBeforeOpenLog are initialized in a thread-safe manner. + * + * NOTE: fileout, mutexDebugLog and sometimes vMsgsBeforeOpenLog + * are leaked on exit. This is ugly, but will be cleaned up by + * the OS/libc. When the shutdown sequence is fully audited and + * tested, explicit destruction of these objects can be implemented. */ static FILE* fileout = NULL; static boost::mutex* mutexDebugLog = NULL; +static list<string> *vMsgsBeforeOpenLog; + +static int FileWriteStr(const std::string &str, FILE *fp) +{ + return fwrite(str.data(), 1, str.size(), fp); +} static void DebugPrintInit() { - assert(fileout == NULL); assert(mutexDebugLog == NULL); + mutexDebugLog = new boost::mutex(); + vMsgsBeforeOpenLog = new list<string>; +} + +void OpenDebugLog() +{ + boost::call_once(&DebugPrintInit, debugPrintInitFlag); + boost::mutex::scoped_lock scoped_lock(*mutexDebugLog); + assert(fileout == NULL); + assert(vMsgsBeforeOpenLog); boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; fileout = fopen(pathDebug.string().c_str(), "a"); if (fileout) setbuf(fileout, NULL); // unbuffered - mutexDebugLog = new boost::mutex(); + // dump buffered messages from before we opened the log + while (!vMsgsBeforeOpenLog->empty()) { + FileWriteStr(vMsgsBeforeOpenLog->front(), fileout); + vMsgsBeforeOpenLog->pop_front(); + } + + delete vMsgsBeforeOpenLog; + vMsgsBeforeOpenLog = NULL; } bool LogAcceptCategory(const char* category) @@ -208,65 +244,92 @@ bool LogAcceptCategory(const char* category) // if not debugging everything and not debugging specific category, LogPrint does nothing. if (setCategories.count(string("")) == 0 && + setCategories.count(string("1")) == 0 && setCategories.count(string(category)) == 0) return false; } return true; } +/** + * fStartedNewLine is a state variable held by the calling context that will + * suppress printing of the timestamp when multiple calls are made that don't + * end in a newline. Initialize it to true, and hold it, in the calling context. + */ +static std::string LogTimestampStr(const std::string &str, bool *fStartedNewLine) +{ + string strStamped; + + if (!fLogTimestamps) + return str; + + if (*fStartedNewLine) + strStamped = DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()) + ' ' + str; + else + strStamped = str; + + if (!str.empty() && str[str.size()-1] == '\n') + *fStartedNewLine = true; + else + *fStartedNewLine = false; + + return strStamped; +} + int LogPrintStr(const std::string &str) { int ret = 0; // Returns total number of characters written + static bool fStartedNewLine = true; if (fPrintToConsole) { // print to console ret = fwrite(str.data(), 1, str.size(), stdout); fflush(stdout); } - else if (fPrintToDebugLog && AreBaseParamsConfigured()) + else if (fPrintToDebugLog) { - static bool fStartedNewLine = true; boost::call_once(&DebugPrintInit, debugPrintInitFlag); - - if (fileout == NULL) - return ret; - boost::mutex::scoped_lock scoped_lock(*mutexDebugLog); - // reopen the log file, if requested - if (fReopenDebugLog) { - fReopenDebugLog = false; - boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; - if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL) - setbuf(fileout, NULL); // unbuffered - } + string strTimestamped = LogTimestampStr(str, &fStartedNewLine); - // Debug print useful for profiling - if (fLogTimestamps && fStartedNewLine) - ret += fprintf(fileout, "%s ", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str()); - if (!str.empty() && str[str.size()-1] == '\n') - fStartedNewLine = true; + // buffer if we haven't opened the log yet + if (fileout == NULL) { + assert(vMsgsBeforeOpenLog); + ret = strTimestamped.length(); + vMsgsBeforeOpenLog->push_back(strTimestamped); + } else - fStartedNewLine = false; - - ret = fwrite(str.data(), 1, str.size(), fileout); + { + // reopen the log file, if requested + if (fReopenDebugLog) { + fReopenDebugLog = false; + boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; + if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL) + setbuf(fileout, NULL); // unbuffered + } + + ret = FileWriteStr(strTimestamped, fileout); + } } - return ret; } -static void InterpretNegativeSetting(string name, map<string, string>& mapSettingsRet) +/** Interpret string as boolean, for argument parsing */ +static bool InterpretBool(const std::string& strValue) { - // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set - if (name.find("-no") == 0) + if (strValue.empty()) + return true; + return (atoi(strValue) != 0); +} + +/** Turn -noX into -X=0 */ +static void InterpretNegativeSetting(std::string& strKey, std::string& strValue) +{ + if (strKey.length()>3 && strKey[0]=='-' && strKey[1]=='n' && strKey[2]=='o') { - std::string positive("-"); - positive.append(name.begin()+3, name.end()); - if (mapSettingsRet.count(positive) == 0) - { - bool value = !GetBoolArg(name, false); - mapSettingsRet[positive] = (value ? "1" : "0"); - } + strKey = "-" + strKey.substr(3); + strValue = InterpretBool(strValue) ? "0" : "1"; } } @@ -298,17 +361,11 @@ void ParseParameters(int argc, const char* const argv[]) // If both --foo and -foo are set, the last takes effect. if (str.length() > 1 && str[1] == '-') str = str.substr(1); + InterpretNegativeSetting(str, strValue); mapArgs[str] = strValue; mapMultiArgs[str].push_back(strValue); } - - // New 0.6 features: - BOOST_FOREACH(const PAIRTYPE(string,string)& entry, mapArgs) - { - // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set - InterpretNegativeSetting(entry.first, mapArgs); - } } std::string GetArg(const std::string& strArg, const std::string& strDefault) @@ -328,11 +385,7 @@ int64_t GetArg(const std::string& strArg, int64_t nDefault) bool GetBoolArg(const std::string& strArg, bool fDefault) { if (mapArgs.count(strArg)) - { - if (mapArgs[strArg].empty()) - return true; - return (atoi(mapArgs[strArg]) != 0); - } + return InterpretBool(mapArgs[strArg]); return fDefault; } @@ -483,13 +536,11 @@ void ReadConfigFile(map<string, string>& mapSettingsRet, { // Don't overwrite existing settings so command line settings override bitcoin.conf string strKey = string("-") + it->string_key; + string strValue = it->value[0]; + InterpretNegativeSetting(strKey, strValue); if (mapSettingsRet.count(strKey) == 0) - { - mapSettingsRet[strKey] = it->value[0]; - // interpret nofoo=1 as foo=0 (and nofoo=0 as foo=1) as long as foo not set) - InterpretNegativeSetting(strKey, mapSettingsRet); - } - mapMultiSettingsRet[strKey].push_back(it->value[0]); + mapSettingsRet[strKey] = strValue; + mapMultiSettingsRet[strKey].push_back(strValue); } // If datadir is changed in .conf file: ClearDatadirCache(); @@ -701,7 +752,7 @@ boost::filesystem::path GetTempPath() { #endif } -void runCommand(std::string strCommand) +void runCommand(const std::string& strCommand) { int nErr = ::system(strCommand.c_str()); if (nErr) @@ -726,21 +777,35 @@ void RenameThread(const char* name) void SetupEnvironment() { - std::locale loc("C"); // On most POSIX systems (e.g. Linux, but not BSD) the environment's locale // may be invalid, in which case the "C" locale is used as fallback. #if !defined(WIN32) && !defined(MAC_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__) try { - loc = std::locale(""); // Raises a runtime error if current locale is invalid + std::locale(""); // Raises a runtime error if current locale is invalid } catch (const std::runtime_error&) { setenv("LC_ALL", "C", 1); } #endif - // The path locale is lazy initialized and to avoid deinitialization errors + // The path locale is lazy initialized and to avoid deinitialization errors // in multithreading environments, it is set explicitly by the main thread. + // A dummy locale is used to extract the internal default locale, used by + // boost::filesystem::path, which is then used to explicitly imbue the path. + std::locale loc = boost::filesystem::path::imbue(std::locale::classic()); boost::filesystem::path::imbue(loc); } +bool SetupNetworking() +{ +#ifdef WIN32 + // Initialize Windows Sockets + WSADATA wsadata; + int ret = WSAStartup(MAKEWORD(2,2), &wsadata); + if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2) + return false; +#endif + return true; +} + void SetThreadPriority(int nPriority) { #ifdef WIN32 @@ -753,3 +818,13 @@ void SetThreadPriority(int nPriority) #endif // PRIO_THREAD #endif // WIN32 } + +int GetNumCores() +{ +#if BOOST_VERSION >= 105600 + return boost::thread::physical_concurrency(); +#else // Must fall back to hardware_concurrency, which unfortunately counts virtual cores + return boost::thread::hardware_concurrency(); +#endif +} + diff --git a/src/util.h b/src/util.h index 483d9d7858..0b2dc01ac6 100644 --- a/src/util.h +++ b/src/util.h @@ -59,6 +59,7 @@ inline std::string _(const char* psz) } void SetupEnvironment(); +bool SetupNetworking(); /** Return true if log accepts specified category */ bool LogAcceptCategory(const char* category); @@ -125,8 +126,9 @@ void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true); #endif boost::filesystem::path GetTempPath(); +void OpenDebugLog(); void ShrinkDebugFile(); -void runCommand(std::string strCommand); +void runCommand(const std::string& strCommand); inline bool IsSwitchChar(char c) { @@ -199,45 +201,15 @@ std::string HelpMessageGroup(const std::string& message); */ std::string HelpMessageOpt(const std::string& option, const std::string& message); -void SetThreadPriority(int nPriority); -void RenameThread(const char* name); - /** - * Standard wrapper for do-something-forever thread functions. - * "Forever" really means until the thread is interrupted. - * Use it like: - * new boost::thread(boost::bind(&LoopForever<void (*)()>, "dumpaddr", &DumpAddresses, 900000)); - * or maybe: - * boost::function<void()> f = boost::bind(&FunctionWithArg, argument); - * threadGroup.create_thread(boost::bind(&LoopForever<boost::function<void()> >, "nothing", f, milliseconds)); + * Return the number of physical cores available on the current system. + * @note This does not count virtual cores, such as those provided by HyperThreading + * when boost is newer than 1.56. */ -template <typename Callable> void LoopForever(const char* name, Callable func, int64_t msecs) -{ - std::string s = strprintf("bitcoin-%s", name); - RenameThread(s.c_str()); - LogPrintf("%s thread start\n", name); - try - { - while (1) - { - MilliSleep(msecs); - func(); - } - } - catch (const boost::thread_interrupted&) - { - LogPrintf("%s thread stop\n", name); - throw; - } - catch (const std::exception& e) { - PrintExceptionContinue(&e, name); - throw; - } - catch (...) { - PrintExceptionContinue(NULL, name); - throw; - } -} +int GetNumCores(); + +void SetThreadPriority(int nPriority); +void RenameThread(const char* name); /** * .. and a wrapper that just calls func once diff --git a/src/utilmoneystr.cpp b/src/utilmoneystr.cpp index 2fbc048878..0f3203432f 100644 --- a/src/utilmoneystr.cpp +++ b/src/utilmoneystr.cpp @@ -11,7 +11,7 @@ using namespace std; -string FormatMoney(const CAmount& n, bool fPlus) +std::string FormatMoney(const CAmount& n) { // Note: not using straight sprintf here because we do NOT want // localized number formatting. @@ -29,8 +29,6 @@ string FormatMoney(const CAmount& n, bool fPlus) if (n < 0) str.insert((unsigned int)0, 1, '-'); - else if (fPlus && n > 0) - str.insert((unsigned int)0, 1, '+'); return str; } diff --git a/src/utilmoneystr.h b/src/utilmoneystr.h index cd9b04810d..99c3ba8306 100644 --- a/src/utilmoneystr.h +++ b/src/utilmoneystr.h @@ -14,7 +14,7 @@ #include "amount.h" -std::string FormatMoney(const CAmount& n, bool fPlus=false); +std::string FormatMoney(const CAmount& n); bool ParseMoney(const std::string& str, CAmount& nRet); bool ParseMoney(const char* pszIn, CAmount& nRet); diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index c15bddc6fb..c5a2b5cdbb 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -14,17 +14,20 @@ using namespace std; -string SanitizeString(const string& str) +static const string CHARS_ALPHA_NUM = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +static const string SAFE_CHARS[] = +{ + CHARS_ALPHA_NUM + " .,;-_/:?@()", // SAFE_CHARS_DEFAULT + CHARS_ALPHA_NUM + " .,;-_?@" // SAFE_CHARS_UA_COMMENT +}; + +string SanitizeString(const string& str, int rule) { - /** - * safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything - * even possibly remotely dangerous like & or > - */ - static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@()"); string strResult; for (std::string::size_type i = 0; i < str.size(); i++) { - if (safeChars.find(str[i]) != std::string::npos) + if (SAFE_CHARS[rule].find(str[i]) != std::string::npos) strResult.push_back(str[i]); } return strResult; @@ -416,12 +419,25 @@ string DecodeBase32(const string& str) return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size()); } +static bool ParsePrechecks(const std::string& str) +{ + if (str.empty()) // No empty string allowed + return false; + if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size()-1]))) // No padding allowed + return false; + if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed + return false; + return true; +} + bool ParseInt32(const std::string& str, int32_t *out) { + if (!ParsePrechecks(str)) + return false; char *endp = NULL; errno = 0; // strtol will not set errno if valid long int n = strtol(str.c_str(), &endp, 10); - if(out) *out = (int)n; + if(out) *out = (int32_t)n; // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit // platforms the size of these types may be different. @@ -430,7 +446,36 @@ bool ParseInt32(const std::string& str, int32_t *out) n <= std::numeric_limits<int32_t>::max(); } -std::string FormatParagraph(const std::string in, size_t width, size_t indent) +bool ParseInt64(const std::string& str, int64_t *out) +{ + if (!ParsePrechecks(str)) + return false; + char *endp = NULL; + errno = 0; // strtoll will not set errno if valid + long long int n = strtoll(str.c_str(), &endp, 10); + if(out) *out = (int64_t)n; + // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow + // we still have to check that the returned value is within the range of an *int64_t*. + return endp && *endp == 0 && !errno && + n >= std::numeric_limits<int64_t>::min() && + n <= std::numeric_limits<int64_t>::max(); +} + +bool ParseDouble(const std::string& str, double *out) +{ + if (!ParsePrechecks(str)) + return false; + if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed + return false; + std::istringstream text(str); + text.imbue(std::locale::classic()); + double result; + text >> result; + if(out) *out = result; + return text.eof() && !text.fail(); +} + +std::string FormatParagraph(const std::string& in, size_t width, size_t indent) { std::stringstream out; size_t col = 0; @@ -497,3 +542,123 @@ int atoi(const std::string& str) { return atoi(str.c_str()); } + +/** Upper bound for mantissa. + * 10^18-1 is the largest arbitrary decimal that will fit in a signed 64-bit integer. + * Larger integers cannot consist of arbitrary combinations of 0-9: + * + * 999999999999999999 1^18-1 + * 9223372036854775807 (1<<63)-1 (max int64_t) + * 9999999999999999999 1^19-1 (would overflow) + */ +static const int64_t UPPER_BOUND = 1000000000000000000LL - 1LL; + +/** Helper function for ParseFixedPoint */ +static inline bool ProcessMantissaDigit(char ch, int64_t &mantissa, int &mantissa_tzeros) +{ + if(ch == '0') + ++mantissa_tzeros; + else { + for (int i=0; i<=mantissa_tzeros; ++i) { + if (mantissa > (UPPER_BOUND / 10LL)) + return false; /* overflow */ + mantissa *= 10; + } + mantissa += ch - '0'; + mantissa_tzeros = 0; + } + return true; +} + +bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out) +{ + int64_t mantissa = 0; + int64_t exponent = 0; + int mantissa_tzeros = 0; + bool mantissa_sign = false; + bool exponent_sign = false; + int ptr = 0; + int end = val.size(); + int point_ofs = 0; + + if (ptr < end && val[ptr] == '-') { + mantissa_sign = true; + ++ptr; + } + if (ptr < end) + { + if (val[ptr] == '0') { + /* pass single 0 */ + ++ptr; + } else if (val[ptr] >= '1' && val[ptr] <= '9') { + while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') { + if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros)) + return false; /* overflow */ + ++ptr; + } + } else return false; /* missing expected digit */ + } else return false; /* empty string or loose '-' */ + if (ptr < end && val[ptr] == '.') + { + ++ptr; + if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') + { + while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') { + if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros)) + return false; /* overflow */ + ++ptr; + ++point_ofs; + } + } else return false; /* missing expected digit */ + } + if (ptr < end && (val[ptr] == 'e' || val[ptr] == 'E')) + { + ++ptr; + if (ptr < end && val[ptr] == '+') + ++ptr; + else if (ptr < end && val[ptr] == '-') { + exponent_sign = true; + ++ptr; + } + if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') { + while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') { + if (exponent > (UPPER_BOUND / 10LL)) + return false; /* overflow */ + exponent = exponent * 10 + val[ptr] - '0'; + ++ptr; + } + } else return false; /* missing expected digit */ + } + if (ptr != end) + return false; /* trailing garbage */ + + /* finalize exponent */ + if (exponent_sign) + exponent = -exponent; + exponent = exponent - point_ofs + mantissa_tzeros; + + /* finalize mantissa */ + if (mantissa_sign) + mantissa = -mantissa; + + /* convert to one 64-bit fixed-point value */ + exponent += decimals; + if (exponent < 0) + return false; /* cannot represent values smaller than 10^-decimals */ + if (exponent >= 18) + return false; /* cannot represent values larger than or equal to 10^(18-decimals) */ + + for (int i=0; i < exponent; ++i) { + if (mantissa > (UPPER_BOUND / 10LL) || mantissa < -(UPPER_BOUND / 10LL)) + return false; /* overflow */ + mantissa *= 10; + } + if (mantissa > UPPER_BOUND || mantissa < -UPPER_BOUND) + return false; /* overflow */ + + if (amount_out) + *amount_out = mantissa; + + return true; +} + diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index b0edd8b542..ce93e83497 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -22,7 +22,21 @@ /** This is needed because the foreach macro can't get over the comma in pair<t1, t2> */ #define PAIRTYPE(t1, t2) std::pair<t1, t2> -std::string SanitizeString(const std::string& str); +/** Used by SanitizeString() */ +enum SafeChars +{ + SAFE_CHARS_DEFAULT, //!< The full set of allowed chars + SAFE_CHARS_UA_COMMENT //!< BIP-0014 subset +}; + +/** +* Remove unsafe chars. Safe chars chosen to allow simple messages/URLs/email +* addresses, but avoid anything even possibly remotely dangerous like & or > +* @param[in] str The string to sanitize +* @param[in] rule The set of safe chars to choose (default: least restrictive) +* @return A new string without unsafe chars +*/ +std::string SanitizeString(const std::string& str, int rule = SAFE_CHARS_DEFAULT); std::vector<unsigned char> ParseHex(const char* psz); std::vector<unsigned char> ParseHex(const std::string& str); signed char HexDigit(char c); @@ -49,6 +63,20 @@ int atoi(const std::string& str); */ bool ParseInt32(const std::string& str, int32_t *out); +/** + * Convert string to signed 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 ParseInt64(const std::string& str, int64_t *out); + +/** + * Convert string to double with strict parse error feedback. + * @returns true if the entire string could be parsed as valid double, + * false if not the entire string could be parsed or when overflow or underflow occurred. + */ +bool ParseDouble(const std::string& str, double *out); + template<typename T> std::string HexStr(const T itbegin, const T itend, bool fSpaces=false) { @@ -74,11 +102,11 @@ inline std::string HexStr(const T& vch, bool fSpaces=false) return HexStr(vch.begin(), vch.end(), fSpaces); } -/** +/** * Format a paragraph of text to a fixed width, adding spaces for * indentation to any added line. */ -std::string FormatParagraph(const std::string in, size_t width=79, size_t indent=0); +std::string FormatParagraph(const std::string& in, size_t width = 79, size_t indent = 0); /** * Timing-attack-resistant comparison. @@ -95,4 +123,11 @@ bool TimingResistantEqual(const T& a, const T& b) return accumulator == 0; } +/** Parse number as fixed point according to JSON number syntax. + * See http://json.org/number.gif + * @returns true on success, false on error. + * @note The result must be in the range (-10^18,10^18), otherwise an overflow error will trigger. + */ +bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out); + #endif // BITCOIN_UTILSTRENCODINGS_H diff --git a/src/utiltime.cpp b/src/utiltime.cpp index 8f0dcae29d..d316288999 100644 --- a/src/utiltime.cpp +++ b/src/utiltime.cpp @@ -30,13 +30,13 @@ void SetMockTime(int64_t nMockTimeIn) int64_t GetTimeMillis() { - return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) - + return (boost::posix_time::microsec_clock::universal_time() - boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds(); } int64_t GetTimeMicros() { - return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) - + return (boost::posix_time::microsec_clock::universal_time() - boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds(); } diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index aa9aefb0de..81f3b775f4 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -13,33 +13,39 @@ 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.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); 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)); g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1)); g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); + g_signals.ScriptForMining.connect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1)); + g_signals.BlockFound.connect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, _1)); } void UnregisterValidationInterface(CValidationInterface* pwalletIn) { + g_signals.BlockFound.disconnect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, _1)); + g_signals.ScriptForMining.disconnect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1)); g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1)); 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.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); + g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1)); } void UnregisterAllValidationInterfaces() { + g_signals.BlockFound.disconnect_all_slots(); + g_signals.ScriptForMining.disconnect_all_slots(); g_signals.BlockChecked.disconnect_all_slots(); g_signals.Broadcast.disconnect_all_slots(); g_signals.Inventory.disconnect_all_slots(); g_signals.SetBestChain.disconnect_all_slots(); g_signals.UpdatedTransaction.disconnect_all_slots(); - g_signals.EraseTransaction.disconnect_all_slots(); g_signals.SyncTransaction.disconnect_all_slots(); + g_signals.UpdatedBlockTip.disconnect_all_slots(); } void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) { diff --git a/src/validationinterface.h b/src/validationinterface.h index b4c93d72ca..ffb56d266b 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -7,9 +7,12 @@ #define BITCOIN_VALIDATIONINTERFACE_H #include <boost/signals2/signal.hpp> +#include <boost/shared_ptr.hpp> class CBlock; struct CBlockLocator; +class CBlockIndex; +class CReserveScript; class CTransaction; class CValidationInterface; class CValidationState; @@ -28,23 +31,25 @@ void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL); class CValidationInterface { protected: - virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {}; - virtual void EraseFromWallet(const uint256 &hash) {}; - virtual void SetBestChain(const CBlockLocator &locator) {}; - virtual void UpdatedTransaction(const uint256 &hash) {}; - virtual void Inventory(const uint256 &hash) {}; - virtual void ResendWalletTransactions(int64_t nBestBlockTime) {}; - virtual void BlockChecked(const CBlock&, const CValidationState&) {}; + virtual void UpdatedBlockTip(const CBlockIndex *pindex) {} + virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {} + virtual void SetBestChain(const CBlockLocator &locator) {} + virtual void UpdatedTransaction(const uint256 &hash) {} + virtual void Inventory(const uint256 &hash) {} + virtual void ResendWalletTransactions(int64_t nBestBlockTime) {} + virtual void BlockChecked(const CBlock&, const CValidationState&) {} + virtual void GetScriptForMining(boost::shared_ptr<CReserveScript>&) {}; + virtual void ResetRequestCount(const uint256 &hash) {}; friend void ::RegisterValidationInterface(CValidationInterface*); friend void ::UnregisterValidationInterface(CValidationInterface*); friend void ::UnregisterAllValidationInterfaces(); }; struct CMainSignals { + /** Notifies listeners of updated block chain tip */ + boost::signals2::signal<void (const CBlockIndex *)> UpdatedBlockTip; /** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */ boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction; - /** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */ - boost::signals2::signal<void (const uint256 &)> EraseTransaction; /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */ boost::signals2::signal<void (const uint256 &)> UpdatedTransaction; /** Notifies listeners of a new active block chain. */ @@ -55,6 +60,10 @@ struct CMainSignals { boost::signals2::signal<void (int64_t nBestBlockTime)> Broadcast; /** Notifies listeners of a block validation result */ boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked; + /** Notifies listeners that a key for mining is required (coinbase) */ + boost::signals2::signal<void (boost::shared_ptr<CReserveScript>&)> ScriptForMining; + /** Notifies listeners that a block has been successfully mined */ + boost::signals2::signal<void (const uint256 &)> BlockFound; }; CMainSignals& GetMainSignals(); diff --git a/src/version.h b/src/version.h index 38b3d2e734..6cdddf9255 100644 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 70002; +static const int PROTOCOL_VERSION = 70011; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -34,4 +34,7 @@ static const int BIP0031_VERSION = 60000; //! "mempool" command, enhanced "getdata" behavior starts with this version static const int MEMPOOL_GD_VERSION = 60002; +//! "filter*" commands are disabled without NODE_BLOOM after and including this version +static const int NO_BLOOM_VERSION = 70011; + #endif // BITCOIN_VERSION_H diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index c7f7e21679..c86ad9758e 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -186,7 +186,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) } if (keyPass && keyFail) { - LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all."); + LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.\n"); assert(false); } if (keyFail || !keyPass) @@ -255,7 +255,7 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co { LOCK(cs_KeyStore); if (!IsCrypted()) - return CKeyStore::GetPubKey(address, vchPubKeyOut); + return CBasicKeyStore::GetPubKey(address, vchPubKeyOut); CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address); if (mi != mapCryptedKeys.end()) @@ -263,6 +263,8 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co vchPubKeyOut = (*mi).second.first; return true; } + // Check for watch-only pubkeys + return CBasicKeyStore::GetPubKey(address, vchPubKeyOut); } return false; } diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 53cfcf0961..e5bc653c33 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(path.string().c_str(), 0); + DbEnv(0).remove(strPath.c_str(), 0); } void CDBEnv::Reset() @@ -78,10 +78,10 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn) boost::this_thread::interruption_point(); - path = pathIn; - boost::filesystem::path pathLogDir = path / "database"; + strPath = pathIn.string(); + boost::filesystem::path pathLogDir = pathIn / "database"; TryCreateDirectory(pathLogDir); - boost::filesystem::path pathErrorFile = path / "db.log"; + boost::filesystem::path pathErrorFile = pathIn / "db.log"; LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string()); unsigned int nEnvFlags = 0; @@ -98,7 +98,7 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn) dbenv->set_flags(DB_AUTO_COMMIT, 1); dbenv->set_flags(DB_TXN_WRITE_NOSYNC, 1); dbenv->log_set_config(DB_LOG_AUTO_REMOVE, 1); - int ret = dbenv->open(path.string().c_str(), + int ret = dbenv->open(strPath.c_str(), DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | @@ -455,7 +455,7 @@ void CDBEnv::Flush(bool fShutdown) dbenv->log_archive(&listp, DB_ARCH_REMOVE); Close(); if (!fMockDb) - boost::filesystem::remove_all(path / "database"); + boost::filesystem::remove_all(boost::filesystem::path(strPath) / "database"); } } } diff --git a/src/wallet/db.h b/src/wallet/db.h index 9596723b21..64071caa3a 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -20,9 +20,6 @@ #include <db_cxx.h> -class CDiskBlockIndex; -class COutPoint; - extern unsigned int nWalletDBUpdated; class CDBEnv @@ -30,7 +27,9 @@ class CDBEnv private: bool fDbEnvInit; bool fMockDb; - boost::filesystem::path path; + // Don't change into boost::filesystem::path, as that can result in + // shutdown problems/crashes caused by a static initialized internal pointer. + std::string strPath; void EnvShutdown(); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index ab951d1d7d..7e22faac37 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" +#include "chain.h" #include "rpcserver.h" #include "init.h" #include "main.h" @@ -19,9 +20,10 @@ #include <boost/algorithm/string.hpp> #include <boost/date_time/posix_time/posix_time.hpp> -#include "json/json_spirit_value.h" +#include "univalue/univalue.h" + +#include <boost/foreach.hpp> -using namespace json_spirit; using namespace std; void EnsureWalletIsUnlocked(); @@ -70,10 +72,10 @@ std::string DecodeDumpString(const std::string &str) { return ret.str(); } -Value importprivkey(const Array& params, bool fHelp) +UniValue importprivkey(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 3) throw runtime_error( @@ -95,6 +97,7 @@ Value importprivkey(const Array& params, bool fHelp) + HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false") ); + LOCK2(cs_main, pwalletMain->cs_wallet); EnsureWalletIsUnlocked(); @@ -109,6 +112,9 @@ Value importprivkey(const Array& params, bool fHelp) if (params.size() > 2) fRescan = params[2].get_bool(); + if (fRescan && fPruneMode) + throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); + CBitcoinSecret vchSecret; bool fGood = vchSecret.SetString(strSecret); @@ -126,7 +132,7 @@ Value importprivkey(const Array& params, bool fHelp) // Don't throw error in case a key is already there if (pwalletMain->HaveKey(vchAddress)) - return Value::null; + return NullUniValue; pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1; @@ -141,46 +147,126 @@ Value importprivkey(const Array& params, bool fHelp) } } - return Value::null; + return NullUniValue; +} + +void ImportAddress(const CBitcoinAddress& address, const string& strLabel); +void ImportScript(const CScript& script, const string& strLabel, bool isRedeemScript) +{ + if (!isRedeemScript && ::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE) + throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); + + pwalletMain->MarkDirty(); + + if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); + + if (isRedeemScript) { + if (!pwalletMain->HaveCScript(script) && !pwalletMain->AddCScript(script)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet"); + ImportAddress(CBitcoinAddress(CScriptID(script)), strLabel); + } +} + +void ImportAddress(const CBitcoinAddress& address, const string& strLabel) +{ + CScript script = GetScriptForDestination(address.Get()); + ImportScript(script, strLabel, false); + // add to address book or update label + if (address.IsValid()) + pwalletMain->SetAddressBook(address.Get(), strLabel, "receive"); } -Value importaddress(const Array& params, bool fHelp) +UniValue importaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 3) + if (fHelp || params.size() < 1 || params.size() > 4) throw runtime_error( - "importaddress \"address\" ( \"label\" rescan )\n" - "\nAdds an address or script (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n" + "importaddress \"address\" ( \"label\" rescan p2sh )\n" + "\nAdds a script (in hex) or address that can be watched as if it were in your wallet but cannot be used to spend.\n" "\nArguments:\n" - "1. \"address\" (string, required) The address\n" + "1. \"script\" (string, required) The hex-encoded script (or address)\n" "2. \"label\" (string, optional, default=\"\") An optional label\n" "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" "\nExamples:\n" - "\nImport an address with rescan\n" - + HelpExampleCli("importaddress", "\"myaddress\"") + + "\nImport a script with rescan\n" + + HelpExampleCli("importaddress", "\"myscript\"") + "\nImport using a label without rescan\n" - + HelpExampleCli("importaddress", "\"myaddress\" \"testing\" false") + + + HelpExampleCli("importaddress", "\"myscript\" \"testing\" false") + "\nAs a JSON-RPC call\n" - + HelpExampleRpc("importaddress", "\"myaddress\", \"testing\", false") + + HelpExampleRpc("importaddress", "\"myscript\", \"testing\", false") ); - LOCK2(cs_main, pwalletMain->cs_wallet); - CScript script; + string strLabel = ""; + if (params.size() > 1) + strLabel = params[1].get_str(); + + // Whether to perform rescan after import + bool fRescan = true; + if (params.size() > 2) + fRescan = params[2].get_bool(); + + if (fRescan && fPruneMode) + throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); + + // Whether to import a p2sh version, too + bool fP2SH = false; + if (params.size() > 3) + fP2SH = params[3].get_bool(); + + LOCK2(cs_main, pwalletMain->cs_wallet); CBitcoinAddress address(params[0].get_str()); if (address.IsValid()) { - script = GetScriptForDestination(address.Get()); + if (fP2SH) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead"); + ImportAddress(address, strLabel); } else if (IsHex(params[0].get_str())) { std::vector<unsigned char> data(ParseHex(params[0].get_str())); - script = CScript(data.begin(), data.end()); + ImportScript(CScript(data.begin(), data.end()), strLabel, fP2SH); } else { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script"); } + if (fRescan) + { + pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); + pwalletMain->ReacceptWalletTransactions(); + } + + return NullUniValue; +} + +UniValue importpubkey(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() < 1 || params.size() > 4) + throw runtime_error( + "importpubkey \"pubkey\" ( \"label\" rescan )\n" + "\nAdds a public key (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n" + "\nArguments:\n" + "1. \"pubkey\" (string, required) The hex-encoded public key\n" + "2. \"label\" (string, optional, default=\"\") An optional label\n" + "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n" + "\nNote: This call can take minutes to complete if rescan is true.\n" + "\nExamples:\n" + "\nImport a public key with rescan\n" + + HelpExampleCli("importpubkey", "\"mypubkey\"") + + "\nImport using a label without rescan\n" + + HelpExampleCli("importpubkey", "\"mypubkey\" \"testing\" false") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("importpubkey", "\"mypubkey\", \"testing\", false") + ); + + string strLabel = ""; if (params.size() > 1) strLabel = params[1].get_str(); @@ -190,37 +276,35 @@ Value importaddress(const Array& params, bool fHelp) if (params.size() > 2) fRescan = params[2].get_bool(); - { - if (::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE) - throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); - - // add to address book or update label - if (address.IsValid()) - pwalletMain->SetAddressBook(address.Get(), strLabel, "receive"); + if (fRescan && fPruneMode) + throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); - // Don't throw error in case an address is already there - if (pwalletMain->HaveWatchOnly(script)) - return Value::null; + if (!IsHex(params[0].get_str())) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey must be a hex string"); + std::vector<unsigned char> data(ParseHex(params[0].get_str())); + CPubKey pubKey(data.begin(), data.end()); + if (!pubKey.IsFullyValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key"); - pwalletMain->MarkDirty(); + LOCK2(cs_main, pwalletMain->cs_wallet); - if (!pwalletMain->AddWatchOnly(script)) - throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); + ImportAddress(CBitcoinAddress(pubKey.GetID()), strLabel); + ImportScript(GetScriptForRawPubKey(pubKey), strLabel, false); - if (fRescan) - { - pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); - pwalletMain->ReacceptWalletTransactions(); - } + if (fRescan) + { + pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); + pwalletMain->ReacceptWalletTransactions(); } - return Value::null; + return NullUniValue; } -Value importwallet(const Array& params, bool fHelp) + +UniValue importwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -237,6 +321,9 @@ Value importwallet(const Array& params, bool fHelp) + HelpExampleRpc("importwallet", "\"test\"") ); + if (fPruneMode) + throw JSONRPCError(RPC_WALLET_ERROR, "Importing wallets is disabled in pruned mode"); + LOCK2(cs_main, pwalletMain->cs_wallet); EnsureWalletIsUnlocked(); @@ -318,13 +405,13 @@ Value importwallet(const Array& params, bool fHelp) if (!fGood) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding some keys to wallet"); - return Value::null; + return NullUniValue; } -Value dumpprivkey(const Array& params, bool fHelp) +UniValue dumpprivkey(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -359,10 +446,10 @@ Value dumpprivkey(const Array& params, bool fHelp) } -Value dumpwallet(const Array& params, bool fHelp) +UniValue dumpwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -421,5 +508,5 @@ Value dumpwallet(const Array& params, bool fHelp) file << "\n"; file << "# End of dump\n"; file.close(); - return Value::null; + return NullUniValue; } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index dd5240e3c0..5d182f3d42 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5,6 +5,7 @@ #include "amount.h" #include "base58.h" +#include "chain.h" #include "core_io.h" #include "init.h" #include "main.h" @@ -21,11 +22,9 @@ #include <boost/assign/list_of.hpp> -#include "json/json_spirit_utils.h" -#include "json/json_spirit_value.h" +#include "univalue/univalue.h" using namespace std; -using namespace json_spirit; int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; @@ -55,7 +54,7 @@ void EnsureWalletIsUnlocked() throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); } -void WalletTxToJSON(const CWalletTx& wtx, Object& entry) +void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) { int confirms = wtx.GetDepthInMainChain(); entry.push_back(Pair("confirmations", confirms)); @@ -69,7 +68,7 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry) } uint256 hash = wtx.GetHash(); entry.push_back(Pair("txid", hash.GetHex())); - Array conflicts; + UniValue conflicts(UniValue::VARR); BOOST_FOREACH(const uint256& conflict, wtx.GetConflicts()) conflicts.push_back(conflict.GetHex()); entry.push_back(Pair("walletconflicts", conflicts)); @@ -79,7 +78,7 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry) entry.push_back(Pair(item.first, item.second)); } -string AccountFromValue(const Value& value) +string AccountFromValue(const UniValue& value) { string strAccount = value.get_str(); if (strAccount == "*") @@ -87,10 +86,10 @@ string AccountFromValue(const Value& value) return strAccount; } -Value getnewaddress(const Array& params, bool fHelp) +UniValue getnewaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 1) throw runtime_error( @@ -166,10 +165,10 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) return CBitcoinAddress(account.vchPubKey.GetID()); } -Value getaccountaddress(const Array& params, bool fHelp) +UniValue getaccountaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -191,17 +190,17 @@ Value getaccountaddress(const Array& params, bool fHelp) // Parse the account first so we don't generate a key if there's an error string strAccount = AccountFromValue(params[0]); - Value ret; + UniValue ret(UniValue::VSTR); ret = GetAccountAddress(strAccount).ToString(); return ret; } -Value getrawchangeaddress(const Array& params, bool fHelp) +UniValue getrawchangeaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 1) throw runtime_error( @@ -233,10 +232,10 @@ Value getrawchangeaddress(const Array& params, bool fHelp) } -Value setaccount(const Array& params, bool fHelp) +UniValue setaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -275,14 +274,14 @@ Value setaccount(const Array& params, bool fHelp) else throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address"); - return Value::null; + return NullUniValue; } -Value getaccount(const Array& params, bool fHelp) +UniValue getaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -311,10 +310,10 @@ Value getaccount(const Array& params, bool fHelp) } -Value getaddressesbyaccount(const Array& params, bool fHelp) +UniValue getaddressesbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -337,7 +336,7 @@ Value getaddressesbyaccount(const Array& params, bool fHelp) string strAccount = AccountFromValue(params[0]); // Find all addresses that have the given account - Array ret; + UniValue ret(UniValue::VARR); BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook) { const CBitcoinAddress& address = item.first; @@ -379,10 +378,10 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr 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."); } -Value sendtoaddress(const Array& params, bool fHelp) +UniValue sendtoaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( @@ -391,7 +390,7 @@ Value sendtoaddress(const Array& params, bool fHelp) + HelpRequiringPassphrase() + "\nArguments:\n" "1. \"bitcoinaddress\" (string, required) The bitcoin address to send to.\n" - "2. \"amount\" (numeric, required) The amount in btc to send. eg 0.1\n" + "2. \"amount\" (numeric, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" " This is not part of the transaction, just kept in your wallet.\n" "4. \"comment-to\" (string, optional) A comment to store the name of the person or organization \n" @@ -416,12 +415,14 @@ Value sendtoaddress(const Array& params, bool fHelp) // Amount CAmount nAmount = AmountFromValue(params[1]); + if (nAmount <= 0) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); // Wallet comments CWalletTx wtx; - if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty()) + if (params.size() > 2 && !params[2].isNull() && !params[2].get_str().empty()) wtx.mapValue["comment"] = params[2].get_str(); - if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) + if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty()) wtx.mapValue["to"] = params[3].get_str(); bool fSubtractFeeFromAmount = false; @@ -435,10 +436,10 @@ Value sendtoaddress(const Array& params, bool fHelp) return wtx.GetHash().GetHex(); } -Value listaddressgroupings(const Array& params, bool fHelp) +UniValue listaddressgroupings(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp) throw runtime_error( @@ -451,7 +452,7 @@ Value listaddressgroupings(const Array& params, bool fHelp) " [\n" " [\n" " \"bitcoinaddress\", (string) The bitcoin address\n" - " amount, (numeric) The amount in btc\n" + " amount, (numeric) The amount in " + CURRENCY_UNIT + "\n" " \"account\" (string, optional) The account (DEPRECATED)\n" " ]\n" " ,...\n" @@ -465,18 +466,17 @@ Value listaddressgroupings(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - Array jsonGroupings; + UniValue jsonGroupings(UniValue::VARR); map<CTxDestination, CAmount> balances = pwalletMain->GetAddressBalances(); BOOST_FOREACH(set<CTxDestination> grouping, pwalletMain->GetAddressGroupings()) { - Array jsonGrouping; + UniValue jsonGrouping(UniValue::VARR); BOOST_FOREACH(CTxDestination address, grouping) { - Array addressInfo; + UniValue addressInfo(UniValue::VARR); addressInfo.push_back(CBitcoinAddress(address).ToString()); addressInfo.push_back(ValueFromAmount(balances[address])); { - LOCK(pwalletMain->cs_wallet); if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end()) addressInfo.push_back(pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get())->second.name); } @@ -487,10 +487,10 @@ Value listaddressgroupings(const Array& params, bool fHelp) return jsonGroupings; } -Value signmessage(const Array& params, bool fHelp) +UniValue signmessage(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 2) throw runtime_error( @@ -543,10 +543,10 @@ Value signmessage(const Array& params, bool fHelp) return EncodeBase64(&vchSig[0], vchSig.size()); } -Value getreceivedbyaddress(const Array& params, bool fHelp) +UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -556,7 +556,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) "1. \"bitcoinaddress\" (string, required) The bitcoin address for transactions.\n" "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "\nResult:\n" - "amount (numeric) The total amount in btc received at this address.\n" + "amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n" "\nExamples:\n" "\nThe amount from transactions with at least 1 confirmation\n" + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") + @@ -588,7 +588,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; - if (wtx.IsCoinBase() || !IsFinalTx(wtx)) + if (wtx.IsCoinBase() || !CheckFinalTx(wtx)) continue; BOOST_FOREACH(const CTxOut& txout, wtx.vout) @@ -601,10 +601,10 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) } -Value getreceivedbyaccount(const Array& params, bool fHelp) +UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -614,7 +614,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) "1. \"account\" (string, required) The selected account, may be the default account using \"\".\n" "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "\nResult:\n" - "amount (numeric) The total amount in btc received for this account.\n" + "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n" "\nExamples:\n" "\nAmount received by the default account with at least 1 confirmation\n" + HelpExampleCli("getreceivedbyaccount", "\"\"") + @@ -642,7 +642,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; - if (wtx.IsCoinBase() || !IsFinalTx(wtx)) + if (wtx.IsCoinBase() || !CheckFinalTx(wtx)) continue; BOOST_FOREACH(const CTxOut& txout, wtx.vout) @@ -666,7 +666,7 @@ CAmount GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; - if (!IsFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0) + if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0) continue; CAmount nReceived, nSent, nFee; @@ -690,10 +690,10 @@ CAmount GetAccountBalance(const string& strAccount, int nMinDepth, const isminef } -Value getbalance(const Array& params, bool fHelp) +UniValue getbalance(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 3) throw runtime_error( @@ -707,7 +707,7 @@ Value getbalance(const Array& params, bool fHelp) "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "3. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress')\n" "\nResult:\n" - "amount (numeric) The total amount in btc received for this account.\n" + "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n" "\nExamples:\n" "\nThe total amount in the wallet\n" + HelpExampleCli("getbalance", "") + @@ -733,12 +733,12 @@ Value getbalance(const Array& params, bool fHelp) if (params[0].get_str() == "*") { // Calculate total balance a different way from GetBalance() // (GetBalance() sums up all unspent TxOuts) - // getbalance and getbalance '*' 0 should return the same number + // getbalance and "getbalance * 1 true" should return the same number CAmount nBalance = 0; for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; - if (!wtx.IsTrusted() || wtx.GetBlocksToMaturity() > 0) + if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0) continue; CAmount allFee; @@ -765,10 +765,10 @@ Value getbalance(const Array& params, bool fHelp) return ValueFromAmount(nBalance); } -Value getunconfirmedbalance(const Array ¶ms, bool fHelp) +UniValue getunconfirmedbalance(const UniValue ¶ms, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 0) throw runtime_error( @@ -781,10 +781,10 @@ Value getunconfirmedbalance(const Array ¶ms, bool fHelp) } -Value movecmd(const Array& params, bool fHelp) +UniValue movecmd(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 3 || params.size() > 5) throw runtime_error( @@ -793,14 +793,15 @@ Value movecmd(const Array& params, bool fHelp) "\nArguments:\n" "1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n" "2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n" - "3. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" - "4. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n" + "3. amount (numeric) Quantity of " + CURRENCY_UNIT + " to move between accounts.\n" + "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" + "5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n" "\nResult:\n" - "true|false (boolean) true if successfull.\n" + "true|false (boolean) true if successful.\n" "\nExamples:\n" - "\nMove 0.01 btc from the default account to the account named tabby\n" + "\nMove 0.01 " + CURRENCY_UNIT + " from the default account to the account named tabby\n" + HelpExampleCli("move", "\"\" \"tabby\" 0.01") + - "\nMove 0.01 btc timotei to akiko with a comment and funds have 6 confirmations\n" + "\nMove 0.01 " + CURRENCY_UNIT + " timotei to akiko with a comment and funds have 6 confirmations\n" + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") + "\nAs a json rpc call\n" + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"") @@ -811,6 +812,8 @@ Value movecmd(const Array& params, bool fHelp) string strFrom = AccountFromValue(params[0]); string strTo = AccountFromValue(params[1]); CAmount nAmount = AmountFromValue(params[2]); + if (nAmount <= 0) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); if (params.size() > 3) // unused parameter, used to be nMinDepth, keep type-checking it though (void)params[3].get_int(); @@ -851,10 +854,10 @@ Value movecmd(const Array& params, bool fHelp) } -Value sendfrom(const Array& params, bool fHelp) +UniValue sendfrom(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 3 || params.size() > 6) throw runtime_error( @@ -865,7 +868,7 @@ Value sendfrom(const Array& params, bool fHelp) "\nArguments:\n" "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n" "2. \"tobitcoinaddress\" (string, required) The bitcoin address to send funds to.\n" - "3. amount (numeric, required) The amount in btc. (transaction fee is added on top).\n" + "3. amount (numeric, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n" "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" " This is not part of the transaction, just kept in your wallet.\n" @@ -875,7 +878,7 @@ Value sendfrom(const Array& params, bool fHelp) "\nResult:\n" "\"transactionid\" (string) The transaction id.\n" "\nExamples:\n" - "\nSend 0.01 btc from the default account to the address, must have at least 1 confirmation\n" + "\nSend 0.01 " + CURRENCY_UNIT + " from the default account to the address, must have at least 1 confirmation\n" + HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") + "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n" + HelpExampleCli("sendfrom", "\"tabby\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") + @@ -890,15 +893,17 @@ Value sendfrom(const Array& params, bool fHelp) if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); CAmount nAmount = AmountFromValue(params[2]); + if (nAmount <= 0) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); int nMinDepth = 1; if (params.size() > 3) nMinDepth = params[3].get_int(); CWalletTx wtx; wtx.strFromAccount = strAccount; - if (params.size() > 4 && params[4].type() != null_type && !params[4].get_str().empty()) + if (params.size() > 4 && !params[4].isNull() && !params[4].get_str().empty()) wtx.mapValue["comment"] = params[4].get_str(); - if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty()) + if (params.size() > 5 && !params[5].isNull() && !params[5].get_str().empty()) wtx.mapValue["to"] = params[5].get_str(); EnsureWalletIsUnlocked(); @@ -914,10 +919,10 @@ Value sendfrom(const Array& params, bool fHelp) } -Value sendmany(const Array& params, bool fHelp) +UniValue sendmany(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( @@ -928,7 +933,7 @@ Value sendmany(const Array& params, bool fHelp) "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n" "2. \"amounts\" (string, required) A json object with addresses and amounts\n" " {\n" - " \"address\":amount (numeric) The bitcoin address is the key, the numeric amount in btc is the value\n" + " \"address\":amount (numeric) The bitcoin address is the key, the numeric amount in " + CURRENCY_UNIT + " is the value\n" " ,...\n" " }\n" "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n" @@ -958,17 +963,17 @@ Value sendmany(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); string strAccount = AccountFromValue(params[0]); - Object sendTo = params[1].get_obj(); + UniValue sendTo = params[1].get_obj(); int nMinDepth = 1; if (params.size() > 2) nMinDepth = params[2].get_int(); CWalletTx wtx; wtx.strFromAccount = strAccount; - if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) + if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty()) wtx.mapValue["comment"] = params[3].get_str(); - Array subtractFeeFromAmount; + UniValue subtractFeeFromAmount(UniValue::VARR); if (params.size() > 4) subtractFeeFromAmount = params[4].get_array(); @@ -976,24 +981,29 @@ Value sendmany(const Array& params, bool fHelp) vector<CRecipient> vecSend; CAmount totalAmount = 0; - BOOST_FOREACH(const Pair& s, sendTo) + vector<string> keys = sendTo.getKeys(); + BOOST_FOREACH(const string& name_, keys) { - CBitcoinAddress address(s.name_); + CBitcoinAddress address(name_); if (!address.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_); if (setAddress.count(address)) - throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_); + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_); setAddress.insert(address); CScript scriptPubKey = GetScriptForDestination(address.Get()); - CAmount nAmount = AmountFromValue(s.value_); + CAmount nAmount = AmountFromValue(sendTo[name_]); + if (nAmount <= 0) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); totalAmount += nAmount; bool fSubtractFeeFromAmount = false; - BOOST_FOREACH(const Value& addr, subtractFeeFromAmount) - if (addr.get_str() == s.name_) + for (unsigned int idx = 0; idx < subtractFeeFromAmount.size(); idx++) { + const UniValue& addr = subtractFeeFromAmount[idx]; + if (addr.get_str() == name_) fSubtractFeeFromAmount = true; + } CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount}; vecSend.push_back(recipient); @@ -1021,12 +1031,12 @@ Value sendmany(const Array& params, bool fHelp) } // Defined in rpcmisc.cpp -extern CScript _createmultisig_redeemScript(const Array& params); +extern CScript _createmultisig_redeemScript(const UniValue& params); -Value addmultisigaddress(const Array& params, bool fHelp) +UniValue addmultisigaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 2 || params.size() > 3) { @@ -1086,7 +1096,7 @@ struct tallyitem } }; -Value ListReceived(const Array& params, bool fByAccounts) +UniValue ListReceived(const UniValue& params, bool fByAccounts) { // Minimum confirmations int nMinDepth = 1; @@ -1109,7 +1119,7 @@ Value ListReceived(const Array& params, bool fByAccounts) { const CWalletTx& wtx = (*it).second; - if (wtx.IsCoinBase() || !IsFinalTx(wtx)) + if (wtx.IsCoinBase() || !CheckFinalTx(wtx)) continue; int nDepth = wtx.GetDepthInMainChain(); @@ -1136,7 +1146,7 @@ Value ListReceived(const Array& params, bool fByAccounts) } // Reply - Array ret; + UniValue ret(UniValue::VARR); map<string, tallyitem> mapAccountTally; BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook) { @@ -1165,14 +1175,14 @@ Value ListReceived(const Array& params, bool fByAccounts) } else { - Object obj; + UniValue obj(UniValue::VOBJ); if(fIsWatchonly) obj.push_back(Pair("involvesWatchonly", true)); obj.push_back(Pair("address", address.ToString())); obj.push_back(Pair("account", strAccount)); obj.push_back(Pair("amount", ValueFromAmount(nAmount))); obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf))); - Array transactions; + UniValue transactions(UniValue::VARR); if (it != mapTally.end()) { BOOST_FOREACH(const uint256& item, (*it).second.txids) @@ -1191,7 +1201,7 @@ Value ListReceived(const Array& params, bool fByAccounts) { CAmount nAmount = (*it).second.nAmount; int nConf = (*it).second.nConf; - Object obj; + UniValue obj(UniValue::VOBJ); if((*it).second.fIsWatchonly) obj.push_back(Pair("involvesWatchonly", true)); obj.push_back(Pair("account", (*it).first)); @@ -1204,10 +1214,10 @@ Value ListReceived(const Array& params, bool fByAccounts) return ret; } -Value listreceivedbyaddress(const Array& params, bool fHelp) +UniValue listreceivedbyaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 3) throw runtime_error( @@ -1224,7 +1234,7 @@ Value listreceivedbyaddress(const Array& params, bool fHelp) " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n" " \"address\" : \"receivingaddress\", (string) The receiving address\n" " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n" - " \"amount\" : x.xxx, (numeric) The total amount in btc received by the address\n" + " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " received by the address\n" " \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n" " }\n" " ,...\n" @@ -1241,10 +1251,10 @@ Value listreceivedbyaddress(const Array& params, bool fHelp) return ListReceived(params, false); } -Value listreceivedbyaccount(const Array& params, bool fHelp) +UniValue listreceivedbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 3) throw runtime_error( @@ -1277,14 +1287,14 @@ Value listreceivedbyaccount(const Array& params, bool fHelp) return ListReceived(params, true); } -static void MaybePushAddress(Object & entry, const CTxDestination &dest) +static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) { CBitcoinAddress addr; if (addr.Set(dest)) entry.push_back(Pair("address", addr.ToString())); } -void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret, const isminefilter& filter) +void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) { CAmount nFee; string strSentAccount; @@ -1301,7 +1311,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe { BOOST_FOREACH(const COutputEntry& s, listSent) { - Object entry; + UniValue entry(UniValue::VOBJ); if(involvesWatchonly || (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY)) entry.push_back(Pair("involvesWatchonly", true)); entry.push_back(Pair("account", strSentAccount)); @@ -1326,7 +1336,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe account = pwalletMain->mapAddressBook[r.destination].name; if (fAllAccounts || (account == strAccount)) { - Object entry; + UniValue entry(UniValue::VOBJ); if(involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY)) entry.push_back(Pair("involvesWatchonly", true)); entry.push_back(Pair("account", account)); @@ -1354,13 +1364,13 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe } } -void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret) +void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, UniValue& ret) { bool fAllAccounts = (strAccount == string("*")); if (fAllAccounts || acentry.strAccount == strAccount) { - Object entry; + UniValue entry(UniValue::VOBJ); entry.push_back(Pair("account", acentry.strAccount)); entry.push_back(Pair("category", "move")); entry.push_back(Pair("time", acentry.nTime)); @@ -1371,10 +1381,10 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar } } -Value listtransactions(const Array& params, bool fHelp) +UniValue listtransactions(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 4) throw runtime_error( @@ -1396,11 +1406,11 @@ Value listtransactions(const Array& params, bool fHelp) " transaction between accounts, and not associated with an address,\n" " transaction id or block. 'send' and 'receive' transactions are \n" " associated with an address, transaction id and block details\n" - " \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the\n" + " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n" " 'move' category for moves outbound. It is positive for the 'receive' category,\n" " and for the 'move' category for inbound funds.\n" " \"vout\" : n, (numeric) the vout value\n" - " \"fee\": x.xxx, (numeric) The amount of the fee in btc. This is negative and only available for the \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" " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n" " 'receive' category of transactions.\n" @@ -1449,7 +1459,7 @@ Value listtransactions(const Array& params, bool fHelp) if (nFrom < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); - Array ret; + UniValue ret(UniValue::VARR); std::list<CAccountingEntry> acentries; CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount); @@ -1472,23 +1482,30 @@ Value listtransactions(const Array& params, bool fHelp) nFrom = ret.size(); if ((nFrom + nCount) > (int)ret.size()) nCount = ret.size() - nFrom; - Array::iterator first = ret.begin(); + + vector<UniValue> arrTmp = ret.getValues(); + + vector<UniValue>::iterator first = arrTmp.begin(); std::advance(first, nFrom); - Array::iterator last = ret.begin(); + vector<UniValue>::iterator last = arrTmp.begin(); std::advance(last, nFrom+nCount); - if (last != ret.end()) ret.erase(last, ret.end()); - if (first != ret.begin()) ret.erase(ret.begin(), first); + if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end()); + if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first); - std::reverse(ret.begin(), ret.end()); // Return oldest to newest + std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest + + ret.clear(); + ret.setArray(); + ret.push_backV(arrTmp); return ret; } -Value listaccounts(const Array& params, bool fHelp) +UniValue listaccounts(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 2) throw runtime_error( @@ -1558,17 +1575,17 @@ Value listaccounts(const Array& params, bool fHelp) BOOST_FOREACH(const CAccountingEntry& entry, acentries) mapAccountBalances[entry.strAccount] += entry.nCreditDebit; - Object ret; + UniValue ret(UniValue::VOBJ); BOOST_FOREACH(const PAIRTYPE(string, CAmount)& accountBalance, mapAccountBalances) { ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second))); } return ret; } -Value listsinceblock(const Array& params, bool fHelp) +UniValue listsinceblock(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp) throw runtime_error( @@ -1584,10 +1601,10 @@ Value listsinceblock(const Array& params, bool fHelp) " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n" " \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n" " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n" - " \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the 'move' category for moves \n" + " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n" " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n" " \"vout\" : n, (numeric) the vout value\n" - " \"fee\": x.xxx, (numeric) The amount of the fee in btc. This is negative and only available for the 'send' category of transactions.\n" + " \"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" @@ -1636,7 +1653,7 @@ Value listsinceblock(const Array& params, bool fHelp) int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1; - Array transactions; + UniValue transactions(UniValue::VARR); for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++) { @@ -1649,17 +1666,17 @@ Value listsinceblock(const Array& params, bool fHelp) CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256(); - Object ret; + UniValue ret(UniValue::VOBJ); ret.push_back(Pair("transactions", transactions)); ret.push_back(Pair("lastblock", lastblock.GetHex())); return ret; } -Value gettransaction(const Array& params, bool fHelp) +UniValue gettransaction(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -1670,7 +1687,7 @@ Value gettransaction(const Array& params, bool fHelp) "2. \"includeWatchonly\" (bool, optional, default=false) Whether to include watchonly addresses in balance calculation and details[]\n" "\nResult:\n" "{\n" - " \"amount\" : x.xxx, (numeric) The transaction amount in btc\n" + " \"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" @@ -1683,7 +1700,7 @@ Value gettransaction(const Array& params, bool fHelp) " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n" " \"address\" : \"bitcoinaddress\", (string) The bitcoin address involved in the transaction\n" " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n" - " \"amount\" : x.xxx (numeric) The amount in btc\n" + " \"amount\" : x.xxx (numeric) The amount in " + CURRENCY_UNIT + "\n" " \"vout\" : n, (numeric) the vout value\n" " }\n" " ,...\n" @@ -1707,7 +1724,7 @@ Value gettransaction(const Array& params, bool fHelp) if(params[1].get_bool()) filter = filter | ISMINE_WATCH_ONLY; - Object entry; + UniValue entry(UniValue::VOBJ); if (!pwalletMain->mapWallet.count(hash)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); const CWalletTx& wtx = pwalletMain->mapWallet[hash]; @@ -1723,7 +1740,7 @@ Value gettransaction(const Array& params, bool fHelp) WalletTxToJSON(wtx, entry); - Array details; + UniValue details(UniValue::VARR); ListTransactions(wtx, "*", 0, false, details, filter); entry.push_back(Pair("details", details)); @@ -1734,10 +1751,10 @@ Value gettransaction(const Array& params, bool fHelp) } -Value backupwallet(const Array& params, bool fHelp) +UniValue backupwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -1756,14 +1773,14 @@ Value backupwallet(const Array& params, bool fHelp) if (!BackupWallet(*pwalletMain, strDest)) throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); - return Value::null; + return NullUniValue; } -Value keypoolrefill(const Array& params, bool fHelp) +UniValue keypoolrefill(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 1) throw runtime_error( @@ -1793,7 +1810,7 @@ Value keypoolrefill(const Array& params, bool fHelp) if (pwalletMain->GetKeyPoolSize() < kpSize) throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool."); - return Value::null; + return NullUniValue; } @@ -1804,10 +1821,10 @@ static void LockWallet(CWallet* pWallet) pWallet->Lock(); } -Value walletpassphrase(const Array& params, bool fHelp) +UniValue walletpassphrase(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( @@ -1860,14 +1877,14 @@ Value walletpassphrase(const Array& params, bool fHelp) nWalletUnlockTime = GetTime() + nSleepTime; RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime); - return Value::null; + return NullUniValue; } -Value walletpassphrasechange(const Array& params, bool fHelp) +UniValue walletpassphrasechange(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( @@ -1906,14 +1923,14 @@ Value walletpassphrasechange(const Array& params, bool fHelp) if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); - return Value::null; + return NullUniValue; } -Value walletlock(const Array& params, bool fHelp) +UniValue walletlock(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0)) throw runtime_error( @@ -1945,14 +1962,14 @@ Value walletlock(const Array& params, bool fHelp) nWalletUnlockTime = 0; } - return Value::null; + return NullUniValue; } -Value encryptwallet(const Array& params, bool fHelp) +UniValue encryptwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1)) throw runtime_error( @@ -2006,10 +2023,10 @@ Value encryptwallet(const Array& params, bool fHelp) return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup."; } -Value lockunspent(const Array& params, bool fHelp) +UniValue lockunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -2050,9 +2067,9 @@ Value lockunspent(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); if (params.size() == 1) - RPCTypeCheck(params, boost::assign::list_of(bool_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VBOOL)); else - RPCTypeCheck(params, boost::assign::list_of(bool_type)(array_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VBOOL)(UniValue::VARR)); bool fUnlock = params[0].get_bool(); @@ -2062,14 +2079,14 @@ Value lockunspent(const Array& params, bool fHelp) return true; } - Array outputs = params[1].get_array(); - BOOST_FOREACH(Value& output, outputs) - { - if (output.type() != obj_type) + UniValue outputs = params[1].get_array(); + for (unsigned int idx = 0; idx < outputs.size(); idx++) { + const UniValue& output = outputs[idx]; + if (!output.isObject()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object"); - const Object& o = output.get_obj(); + const UniValue& o = output.get_obj(); - RPCTypeCheck(o, boost::assign::map_list_of("txid", str_type)("vout", int_type)); + RPCTypeCheckObj(o, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)); string txid = find_value(o, "txid").get_str(); if (!IsHex(txid)) @@ -2090,10 +2107,10 @@ Value lockunspent(const Array& params, bool fHelp) return true; } -Value listlockunspent(const Array& params, bool fHelp) +UniValue listlockunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 0) throw runtime_error( @@ -2126,10 +2143,10 @@ Value listlockunspent(const Array& params, bool fHelp) vector<COutPoint> vOutpts; pwalletMain->ListLockedCoins(vOutpts); - Array ret; + UniValue ret(UniValue::VARR); BOOST_FOREACH(COutPoint &outpt, vOutpts) { - Object o; + UniValue o(UniValue::VOBJ); o.push_back(Pair("txid", outpt.hash.GetHex())); o.push_back(Pair("vout", (int)outpt.n)); @@ -2139,17 +2156,17 @@ Value listlockunspent(const Array& params, bool fHelp) return ret; } -Value settxfee(const Array& params, bool fHelp) +UniValue settxfee(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 1) throw runtime_error( "settxfee amount\n" "\nSet the transaction fee per kB.\n" "\nArguments:\n" - "1. amount (numeric, required) The transaction fee in BTC/kB rounded to the nearest 0.00000001\n" + "1. amount (numeric, required) The transaction fee in " + CURRENCY_UNIT + "/kB rounded to the nearest 0.00000001\n" "\nResult\n" "true|false (boolean) Returns true if successful\n" "\nExamples:\n" @@ -2160,18 +2177,16 @@ Value settxfee(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); // Amount - CAmount nAmount = 0; - if (params[0].get_real() != 0.0) - nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts + CAmount nAmount = AmountFromValue(params[0]); payTxFee = CFeeRate(nAmount, 1000); return true; } -Value getwalletinfo(const Array& params, bool fHelp) +UniValue getwalletinfo(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 0) throw runtime_error( @@ -2180,13 +2195,14 @@ Value getwalletinfo(const Array& params, bool fHelp) "\nResult:\n" "{\n" " \"walletversion\": xxxxx, (numeric) the wallet version\n" - " \"balance\": xxxxxxx, (numeric) the total confirmed bitcoin balance of the wallet\n" - " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed bitcoin balance of the wallet\n" - " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet\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" "}\n" "\nExamples:\n" + HelpExampleCli("getwalletinfo", "") @@ -2195,7 +2211,7 @@ Value getwalletinfo(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance()))); @@ -2205,13 +2221,14 @@ Value getwalletinfo(const Array& params, bool fHelp) obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize())); if (pwalletMain->IsCrypted()) obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); + obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); return obj; } -Value resendwallettransactions(const Array& params, bool fHelp) +UniValue resendwallettransactions(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 0) throw runtime_error( @@ -2225,7 +2242,7 @@ Value resendwallettransactions(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); std::vector<uint256> txids = pwalletMain->ResendWalletTransactionsBefore(GetTime()); - Array result; + UniValue result(UniValue::VARR); BOOST_FOREACH(const uint256& txid, txids) { result.push_back(txid.ToString()); @@ -2233,10 +2250,10 @@ Value resendwallettransactions(const Array& params, bool fHelp) return result; } -Value listunspent(const Array& params, bool fHelp) +UniValue listunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 3) throw runtime_error( @@ -2262,7 +2279,7 @@ Value listunspent(const Array& params, bool fHelp) " \"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 btc\n" + " \"amount\" : x.xxx, (numeric) the transaction amount in " + CURRENCY_UNIT + "\n" " \"confirmations\" : n (numeric) The number of confirmations\n" " }\n" " ,...\n" @@ -2274,7 +2291,7 @@ Value listunspent(const Array& params, bool fHelp) + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") ); - RPCTypeCheck(params, boost::assign::list_of(int_type)(int_type)(array_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)(UniValue::VNUM)(UniValue::VARR)); int nMinDepth = 1; if (params.size() > 0) @@ -2286,8 +2303,9 @@ Value listunspent(const Array& params, bool fHelp) set<CBitcoinAddress> setAddress; if (params.size() > 2) { - Array inputs = params[2].get_array(); - BOOST_FOREACH(Value& input, inputs) { + UniValue inputs = params[2].get_array(); + for (unsigned int idx = 0; idx < inputs.size(); idx++) { + const UniValue& input = inputs[idx]; CBitcoinAddress address(input.get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str()); @@ -2297,7 +2315,7 @@ Value listunspent(const Array& params, bool fHelp) } } - Array results; + UniValue results(UniValue::VARR); vector<COutput> vecOutputs; assert(pwalletMain != NULL); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -2317,7 +2335,7 @@ Value listunspent(const Array& params, bool fHelp) CAmount nValue = out.tx->vout[out.i].nValue; const CScript& pk = out.tx->vout[out.i].scriptPubKey; - Object entry; + UniValue entry(UniValue::VOBJ); entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); entry.push_back(Pair("vout", out.i)); CTxDestination address; @@ -2343,4 +2361,67 @@ Value listunspent(const Array& params, bool fHelp) } return results; -}
\ No newline at end of file +} + +UniValue fundrawtransaction(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "fundrawtransaction \"hexstring\" includeWatching\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" + "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" + "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" + "\nResult:\n" + "{\n" + " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n" + " \"fee\": n, (numeric) The fee added to the transaction\n" + " \"changepos\": n (numeric) The position of the added change output, or -1\n" + "}\n" + "\"hex\" \n" + "\nExamples:\n" + "\nCreate a transaction with no inputs\n" + + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") + + "\nAdd sufficient unsigned inputs to meet the output value\n" + + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") + + "\nSign the transaction\n" + + HelpExampleCli("signrawtransaction", "\"fundedtransactionhex\"") + + "\nSend the transaction\n" + + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") + ); + + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL)); + + // parse hex string from parameter + CTransaction origTx; + if (!DecodeHexTx(origTx, params[0].get_str())) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + + bool includeWatching = false; + if (params.size() > 1) + includeWatching = true; + + CMutableTransaction tx(origTx); + CAmount nFee; + string strFailReason; + int nChangePos = -1; + if(!pwalletMain->FundTransaction(tx, nFee, nChangePos, strFailReason, includeWatching)) + 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("fee", ValueFromAmount(nFee))); + + return result; +} diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 75337d4a7d..bd3004061b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -7,13 +7,21 @@ #include "base58.h" #include "checkpoints.h" +#include "chain.h" #include "coincontrol.h" #include "consensus/consensus.h" +#include "consensus/validation.h" +#include "key.h" +#include "keystore.h" #include "main.h" #include "net.h" +#include "policy/policy.h" +#include "primitives/block.h" +#include "primitives/transaction.h" #include "script/script.h" #include "script/sign.h" #include "timedata.h" +#include "txmempool.h" #include "util.h" #include "utilmoneystr.h" @@ -30,13 +38,13 @@ using namespace std; */ CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; -unsigned int nTxConfirmTarget = 1; +unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET; bool bSpendZeroConfChange = true; bool fSendFreeTransactions = false; bool fPayAtLeastCustomFee = true; -/** - * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) +/** + * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) * Override with -mintxfee */ CFeeRate CWallet::minTxFee = CFeeRate(1000); @@ -106,6 +114,9 @@ bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey) script = GetScriptForDestination(pubkey.GetID()); if (HaveWatchOnly(script)) RemoveWatchOnly(script); + script = GetScriptForRawPubKey(pubkey); + if (HaveWatchOnly(script)) + RemoveWatchOnly(script); if (!fFileBacked) return true; @@ -418,6 +429,7 @@ void CWallet::SyncMetaData(pair<TxSpends::iterator, TxSpends::iterator> range) const uint256& hash = it->second; CWalletTx* copyTo = &mapWallet[hash]; if (copyFrom == copyTo) continue; + if (!copyFrom->IsEquivalentTo(*copyTo)) continue; copyTo->mapValue = copyFrom->mapValue; copyTo->vOrderForm = copyFrom->vOrderForm; // fTimeReceivedIsTxTime not copied on purpose @@ -529,7 +541,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) delete pwalletdbEncryption; } // We now probably have half of our keys encrypted in memory, and half not... - // die and let the user reload their unencrypted wallet. + // die and let the user reload the unencrypted wallet. assert(false); } @@ -541,7 +553,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) if (!pwalletdbEncryption->TxnCommit()) { delete pwalletdbEncryption; // We now have keys encrypted in memory, but not on disk... - // die to avoid confusion and let the user reload their unencrypted wallet. + // die to avoid confusion and let the user reload the unencrypted wallet. assert(false); } @@ -690,9 +702,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD wtx.hashBlock = wtxIn.hashBlock; fUpdated = true; } - if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex)) + if (wtxIn.nIndex != -1 && (wtxIn.nIndex != wtx.nIndex)) { - wtx.vMerkleBranch = wtxIn.vMerkleBranch; wtx.nIndex = wtxIn.nIndex; fUpdated = true; } @@ -775,18 +786,6 @@ void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock) } } -void CWallet::EraseFromWallet(const uint256 &hash) -{ - if (!fFileBacked) - return; - { - LOCK(cs_wallet); - if (mapWallet.erase(hash)) - CWalletDB(strWalletFile).EraseTx(hash); - } - return; -} - isminetype CWallet::IsMine(const CTxIn &txin) const { @@ -1059,6 +1058,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) { int ret = 0; int64_t nNow = GetTime(); + const CChainParams& chainParams = Params(); CBlockIndex* pindex = pindexStart; { @@ -1070,12 +1070,12 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) pindex = chainActive.Next(pindex); ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup - double dProgressStart = Checkpoints::GuessVerificationProgress(pindex, false); - double dProgressTip = Checkpoints::GuessVerificationProgress(chainActive.Tip(), false); + double dProgressStart = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false); + double dProgressTip = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip(), false); while (pindex) { if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0) - ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100)))); + ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100)))); CBlock block; ReadBlockFromDisk(block, pindex); @@ -1087,7 +1087,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) pindex = chainActive.Next(pindex); if (GetTime() >= nNow + 60) { nNow = GetTime(); - LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(pindex)); + LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex)); } } ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI @@ -1097,7 +1097,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) void CWallet::ReacceptWalletTransactions() { - // If transcations aren't broadcasted, don't let them into local mempool either + // If transactions aren't being broadcasted, don't let them into local mempool either if (!fBroadcastTransactions) return; LOCK2(cs_main, cs_wallet); @@ -1316,7 +1316,7 @@ CAmount CWalletTx::GetChange() const bool CWalletTx::IsTrusted() const { // Quick answer in most cases - if (!IsFinalTx(*this)) + if (!CheckFinalTx(*this)) return false; int nDepth = GetDepthInMainChain(); if (nDepth >= 1) @@ -1340,6 +1340,15 @@ bool CWalletTx::IsTrusted() const return true; } +bool CWalletTx::IsEquivalentTo(const CWalletTx& tx) const +{ + CMutableTransaction tx1 = *this; + CMutableTransaction tx2 = tx; + for (unsigned int i = 0; i < tx1.vin.size(); i++) tx1.vin[i].scriptSig = CScript(); + for (unsigned int i = 0; i < tx2.vin.size(); i++) tx2.vin[i].scriptSig = CScript(); + return CTransaction(tx1) == CTransaction(tx2); +} + std::vector<uint256> CWallet::ResendWalletTransactionsBefore(int64_t nTime) { std::vector<uint256> result; @@ -1422,7 +1431,7 @@ CAmount CWallet::GetUnconfirmedBalance() const for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; - if (!IsFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0)) + if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0)) nTotal += pcoin->GetAvailableCredit(); } } @@ -1467,7 +1476,7 @@ CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; - if (!IsFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0)) + if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0)) nTotal += pcoin->GetAvailableWatchOnlyCredit(); } } @@ -1502,7 +1511,7 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const const uint256& wtxid = it->first; const CWalletTx* pcoin = &(*it).second; - if (!IsFinalTx(*pcoin)) + if (!CheckFinalTx(*pcoin)) continue; if (fOnlyConfirmed && !pcoin->IsTrusted()) @@ -1519,8 +1528,10 @@ void CWallet::AvailableCoins(vector<COutput>& 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->IsSelected((*it).first, i))) - vCoins.push_back(COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO)); + (!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))); } } } @@ -1679,25 +1690,109 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx* AvailableCoins(vCoins, true, coinControl); // coin control -> return all selected outputs (we want all selected to go into the transaction for sure) - if (coinControl && coinControl->HasSelected()) + if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs) { BOOST_FOREACH(const COutput& out, vCoins) { - if(!out.fSpendable) - continue; + if (!out.fSpendable) + continue; nValueRet += out.tx->vout[out.i].nValue; setCoinsRet.insert(make_pair(out.tx, out.i)); } return (nValueRet >= nTargetValue); } - return (SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet) || - SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet) || - (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet))); + // calculate value from preset inputs and store them + set<pair<const CWalletTx*, uint32_t> > setPresetCoins; + CAmount nValueFromPresetInputs = 0; + + std::vector<COutPoint> vPresetInputs; + if (coinControl) + coinControl->ListSelected(vPresetInputs); + BOOST_FOREACH(const COutPoint& outpoint, vPresetInputs) + { + map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash); + if (it != mapWallet.end()) + { + const CWalletTx* pcoin = &it->second; + // Clearly invalid input, fail + if (pcoin->vout.size() <= outpoint.n) + return false; + nValueFromPresetInputs += pcoin->vout[outpoint.n].nValue; + setPresetCoins.insert(make_pair(pcoin, outpoint.n)); + } else + return false; // TODO: Allow non-wallet inputs + } + + // remove preset inputs from vCoins + for (vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->HasSelected();) + { + if (setPresetCoins.count(make_pair(it->tx, it->i))) + it = vCoins.erase(it); + else + ++it; + } + + 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)); + + // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset + setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end()); + + // add preset inputs to the total value selected + nValueRet += nValueFromPresetInputs; + + return res; +} + +bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching) +{ + vector<CRecipient> vecSend; + + // Turn the txout set into a CRecipient vector + BOOST_FOREACH(const CTxOut& txOut, tx.vout) + { + CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, false}; + vecSend.push_back(recipient); + } + + CCoinControl coinControl; + coinControl.fAllowOtherInputs = true; + coinControl.fAllowWatchOnly = includeWatching; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + coinControl.Select(txin.prevout); + + CReserveKey reservekey(this); + CWalletTx wtx; + if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosRet, strFailReason, &coinControl, false)) + return false; + + if (nChangePosRet != -1) + tx.vout.insert(tx.vout.begin() + nChangePosRet, wtx.vout[nChangePosRet]); + + // 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) + tx.vin.push_back(txin); + } + + return true; } -bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, - CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl) +bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, + int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign) { CAmount nValue = 0; unsigned int nSubtractFeeFromAmount = 0; @@ -1897,23 +1992,43 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, // Sign int nIn = 0; + CTransaction txNewConst(txNew); BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) - if (!SignSignature(*this, *coin.first, txNew, nIn++)) + { + bool signSuccess; + const CScript& scriptPubKey = coin.first->vout[coin.second].scriptPubKey; + CScript& scriptSigRes = txNew.vin[nIn].scriptSig; + if (sign) + signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, SIGHASH_ALL), scriptPubKey, scriptSigRes); + else + signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, scriptSigRes); + + if (!signSuccess) { strFailReason = _("Signing transaction failed"); return false; } + nIn++; + } + + unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION); + + // Remove scriptSigs if we used dummy signatures for fee calculation + if (!sign) { + BOOST_FOREACH (CTxIn& vin, txNew.vin) + vin.scriptSig = CScript(); + } // Embed the constructed transaction data in wtxNew. *static_cast<CTransaction*>(&wtxNew) = CTransaction(txNew); // Limit size - unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION); if (nBytes >= MAX_STANDARD_TX_SIZE) { strFailReason = _("Transaction too large"); return false; } + dPriority = wtxNew.ComputePriority(dPriority, nBytes); // Can we complete this as a free transaction? @@ -1996,7 +2111,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) if (!wtxNew.AcceptToMemoryPool(false)) { // This must not fail. The transaction has already been signed and recorded. - LogPrintf("CommitTransaction(): Error: Transaction not valid"); + LogPrintf("CommitTransaction(): Error: Transaction not valid\n"); return false; } wtxNew.RelayWalletTransaction(); @@ -2286,7 +2401,7 @@ std::map<CTxDestination, CAmount> CWallet::GetAddressBalances() { CWalletTx *pcoin = &walletEntry.second; - if (!IsFinalTx(*pcoin) || !pcoin->IsTrusted()) + if (!CheckFinalTx(*pcoin) || !pcoin->IsTrusted()) continue; if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) @@ -2409,7 +2524,7 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings() return ret; } -set<CTxDestination> CWallet::GetAccountAddresses(string strAccount) const +std::set<CTxDestination> CWallet::GetAccountAddresses(const std::string& strAccount) const { LOCK(cs_wallet); set<CTxDestination> result; @@ -2487,6 +2602,17 @@ void CWallet::UpdatedTransaction(const uint256 &hashTx) } } +void CWallet::GetScriptForMining(boost::shared_ptr<CReserveScript> &script) +{ + boost::shared_ptr<CReserveKey> rKey(new CReserveKey(this)); + CPubKey pubkey; + if (!rKey->GetReservedKey(pubkey)) + return; + + script = rKey; + script->reserveScript = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; +} + void CWallet::LockCoin(COutPoint& output) { AssertLockHeld(cs_wallet); // setLockedCoins @@ -2682,15 +2808,11 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block) break; if (nIndex == (int)block.vtx.size()) { - vMerkleBranch.clear(); nIndex = -1; LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n"); return 0; } - // Fill in merkle branch - vMerkleBranch = block.GetMerkleBranch(nIndex); - // Is the tx in a block that's in the main chain BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi == mapBlockIndex.end()) @@ -2716,14 +2838,6 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const if (!pindex || !chainActive.Contains(pindex)) return 0; - // Make sure the merkle branch connects to this block - if (!fMerkleVerified) - { - if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot) - return 0; - fMerkleVerified = true; - } - pindexRet = pindex; return chainActive.Height() - pindex->nHeight + 1; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 1c900b0315..34e98cfb81 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -7,10 +7,7 @@ #define BITCOIN_WALLET_WALLET_H #include "amount.h" -#include "key.h" -#include "keystore.h" -#include "primitives/block.h" -#include "primitives/transaction.h" +#include "streams.h" #include "tinyformat.h" #include "ui_interface.h" #include "utilstrencodings.h" @@ -28,6 +25,8 @@ #include <utility> #include <vector> +#include <boost/shared_ptr.hpp> + /** * Settings */ @@ -44,6 +43,8 @@ static const CAmount DEFAULT_TRANSACTION_FEE = 0; static const CAmount nHighTransactionFeeWarning = 0.01 * COIN; //! -maxtxfee default static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN; +//! -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 @@ -150,13 +151,8 @@ private: public: uint256 hashBlock; - std::vector<uint256> vMerkleBranch; int nIndex; - // memory only - mutable bool fMerkleVerified; - - CMerkleTx() { Init(); @@ -171,13 +167,13 @@ public: { hashBlock = uint256(); nIndex = -1; - fMerkleVerified = false; } ADD_SERIALIZE_METHODS; template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + std::vector<uint256> vMerkleBranch; // For compatibility with older versions. READWRITE(*(CTransaction*)this); nVersion = this->nVersion; READWRITE(hashBlock); @@ -374,6 +370,9 @@ public: return (GetDebit(filter) > 0); } + // True if only scriptSigs are different + bool IsEquivalentTo(const CWalletTx& tx) const; + bool IsTrusted() const; bool WriteToDisk(CWalletDB *pwalletdb); @@ -494,7 +493,7 @@ public: SetNull(); } - CWallet(std::string strWalletFileIn) + CWallet(const std::string& strWalletFileIn) { SetNull(); @@ -613,7 +612,6 @@ public: bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb); void SyncTransaction(const CTransaction& tx, const CBlock* pblock); bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate); - void EraseFromWallet(const uint256 &hash); int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); void ReacceptWalletTransactions(); void ResendWalletTransactions(int64_t nBestBlockTime); @@ -624,8 +622,9 @@ public: CAmount GetWatchOnlyBalance() const; CAmount GetUnconfirmedWatchOnlyBalance() const; CAmount GetImmatureWatchOnlyBalance() const; - bool CreateTransaction(const std::vector<CRecipient>& vecSend, - CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl *coinControl = NULL); + bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching); + bool CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, + std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); static CFeeRate minTxFee; @@ -643,7 +642,7 @@ public: std::set< std::set<CTxDestination> > GetAddressGroupings(); std::map<CTxDestination, CAmount> GetAddressBalances(); - std::set<CTxDestination> GetAccountAddresses(std::string strAccount) const; + std::set<CTxDestination> GetAccountAddresses(const std::string& strAccount) const; isminetype IsMine(const CTxIn& txin) const; CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const; @@ -678,6 +677,13 @@ public: } } + void GetScriptForMining(boost::shared_ptr<CReserveScript> &script); + void ResetRequestCount(const uint256 &hash) + { + LOCK(cs_wallet); + mapRequestCount[hash] = 0; + }; + unsigned int GetKeyPoolSize() { AssertLockHeld(cs_wallet); // setKeyPool @@ -733,7 +739,7 @@ public: }; /** A key allocated from the key pool. */ -class CReserveKey +class CReserveKey : public CReserveScript { protected: CWallet* pwallet; @@ -754,6 +760,7 @@ public: void ReturnKey(); bool GetReservedKey(CPubKey &pubkey); void KeepKey(); + void KeepScript() { KeepKey(); } }; diff --git a/src/wallet/wallet_ismine.cpp b/src/wallet/wallet_ismine.cpp index 5482348e35..d27b1531e3 100644 --- a/src/wallet/wallet_ismine.cpp +++ b/src/wallet/wallet_ismine.cpp @@ -9,6 +9,7 @@ #include "keystore.h" #include "script/script.h" #include "script/standard.h" +#include "script/sign.h" #include <boost/foreach.hpp> @@ -40,7 +41,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) txnouttype whichType; if (!Solver(scriptPubKey, whichType, vSolutions)) { if (keystore.HaveWatchOnly(scriptPubKey)) - return ISMINE_WATCH_ONLY; + return ISMINE_WATCH_UNSOLVABLE; return ISMINE_NO; } @@ -85,7 +86,10 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) } } - if (keystore.HaveWatchOnly(scriptPubKey)) - return ISMINE_WATCH_ONLY; + 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; + } return ISMINE_NO; } diff --git a/src/wallet/wallet_ismine.h b/src/wallet/wallet_ismine.h index 5b9b0e0841..9f45f76c6b 100644 --- a/src/wallet/wallet_ismine.h +++ b/src/wallet/wallet_ismine.h @@ -6,9 +6,10 @@ #ifndef BITCOIN_WALLET_WALLET_ISMINE_H #define BITCOIN_WALLET_WALLET_ISMINE_H -#include "key.h" #include "script/standard.h" +#include <stdint.h> + class CKeyStore; class CScript; @@ -16,8 +17,12 @@ class CScript; enum isminetype { ISMINE_NO = 0, - ISMINE_WATCH_ONLY = 1, - ISMINE_SPENDABLE = 2, + //! Indicates that we dont 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, + ISMINE_WATCH_ONLY = ISMINE_WATCH_SOLVABLE | ISMINE_WATCH_UNSOLVABLE, + ISMINE_SPENDABLE = 4, ISMINE_ALL = ISMINE_WATCH_ONLY | ISMINE_SPENDABLE }; /** used for bitflags of isminetype */ diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index de56a2d1af..0624e442d1 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -6,7 +6,8 @@ #include "wallet/walletdb.h" #include "base58.h" -#include "main.h" +#include "consensus/validation.h" +#include "main.h" // For CheckTransaction #include "protocol.h" #include "serialize.h" #include "sync.h" @@ -130,12 +131,14 @@ bool CWalletDB::EraseWatchOnly(const CScript &dest) bool CWalletDB::WriteBestBlock(const CBlockLocator& locator) { nWalletDBUpdated++; - return Write(std::string("bestblock"), locator); + Write(std::string("bestblock"), CBlockLocator()); // Write empty block locator so versions that require a merkle branch automatically rescan + return Write(std::string("bestblock_nomerkle"), locator); } bool CWalletDB::ReadBestBlock(CBlockLocator& locator) { - return Read(std::string("bestblock"), locator); + if (Read(std::string("bestblock"), locator) && !locator.vHave.empty()) return true; + return Read(std::string("bestblock_nomerkle"), locator); } bool CWalletDB::WriteOrderPosNext(int64_t nOrderPosNext) @@ -915,7 +918,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKe } std::vector<CDBEnv::KeyValPair> salvagedData; - bool allOK = dbenv.Salvage(newFilename, true, salvagedData); + bool fSuccess = dbenv.Salvage(newFilename, true, salvagedData); if (salvagedData.empty()) { LogPrintf("Salvage(aggressive) found no records in %s.\n", newFilename); @@ -923,7 +926,6 @@ bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKe } LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size()); - bool fSuccess = allOK; boost::scoped_ptr<Db> pdbCopy(new Db(dbenv.dbenv, 0)); int ret = pdbCopy->open(NULL, // Txn pointer filename.c_str(), // Filename diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index bc1a104b5b..270f826aed 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -9,7 +9,6 @@ #include "amount.h" #include "wallet/db.h" #include "key.h" -#include "keystore.h" #include <list> #include <stdint.h> diff --git a/src/zmq/zmqabstractnotifier.cpp b/src/zmq/zmqabstractnotifier.cpp new file mode 100644 index 0000000000..9f5cb3ba67 --- /dev/null +++ b/src/zmq/zmqabstractnotifier.cpp @@ -0,0 +1,22 @@ +// 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 "zmqabstractnotifier.h" +#include "util.h" + + +CZMQAbstractNotifier::~CZMQAbstractNotifier() +{ + assert(!psocket); +} + +bool CZMQAbstractNotifier::NotifyBlock(const CBlockIndex * /*CBlockIndex*/) +{ + return true; +} + +bool CZMQAbstractNotifier::NotifyTransaction(const CTransaction &/*transaction*/) +{ + return true; +} diff --git a/src/zmq/zmqabstractnotifier.h b/src/zmq/zmqabstractnotifier.h new file mode 100644 index 0000000000..77cf5141e2 --- /dev/null +++ b/src/zmq/zmqabstractnotifier.h @@ -0,0 +1,44 @@ +// 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_ZMQ_ZMQABSTRACTNOTIFIER_H +#define BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H + +#include "zmqconfig.h" + +class CBlockIndex; +class CZMQAbstractNotifier; + +typedef CZMQAbstractNotifier* (*CZMQNotifierFactory)(); + +class CZMQAbstractNotifier +{ +public: + CZMQAbstractNotifier() : psocket(0) { } + virtual ~CZMQAbstractNotifier(); + + template <typename T> + static CZMQAbstractNotifier* Create() + { + return new T(); + } + + std::string GetType() const { return type; } + void SetType(const std::string &t) { type = t; } + std::string GetAddress() const { return address; } + void SetAddress(const std::string &a) { address = a; } + + virtual bool Initialize(void *pcontext) = 0; + virtual void Shutdown() = 0; + + virtual bool NotifyBlock(const CBlockIndex *pindex); + virtual bool NotifyTransaction(const CTransaction &transaction); + +protected: + void *psocket; + std::string type; + std::string address; +}; + +#endif // BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H diff --git a/src/zmq/zmqconfig.h b/src/zmq/zmqconfig.h new file mode 100644 index 0000000000..6057f5d1a0 --- /dev/null +++ b/src/zmq/zmqconfig.h @@ -0,0 +1,24 @@ +// 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_ZMQ_ZMQCONFIG_H +#define BITCOIN_ZMQ_ZMQCONFIG_H + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include <stdarg.h> +#include <string> + +#if ENABLE_ZMQ +#include <zmq.h> +#endif + +#include "primitives/block.h" +#include "primitives/transaction.h" + +void zmqError(const char *str); + +#endif // BITCOIN_ZMQ_ZMQCONFIG_H diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp new file mode 100644 index 0000000000..388b86707b --- /dev/null +++ b/src/zmq/zmqnotificationinterface.cpp @@ -0,0 +1,155 @@ +// 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 "zmqnotificationinterface.h" +#include "zmqpublishnotifier.h" + +#include "version.h" +#include "main.h" +#include "streams.h" +#include "util.h" + +void zmqError(const char *str) +{ + LogPrint("zmq", "Error: %s, errno=%s\n", str, zmq_strerror(errno)); +} + +CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(NULL) +{ +} + +CZMQNotificationInterface::~CZMQNotificationInterface() +{ + // ensure Shutdown if Initialize is called + assert(!pcontext); + + for (std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); i!=notifiers.end(); ++i) + { + delete *i; + } +} + +CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const std::map<std::string, std::string> &args) +{ + CZMQNotificationInterface* notificationInterface = NULL; + std::map<std::string, CZMQNotifierFactory> factories; + std::list<CZMQAbstractNotifier*> notifiers; + + factories["pubhashblock"] = CZMQAbstractNotifier::Create<CZMQPublishHashBlockNotifier>; + factories["pubhashtx"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionNotifier>; + factories["pubrawblock"] = CZMQAbstractNotifier::Create<CZMQPublishRawBlockNotifier>; + factories["pubrawtx"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionNotifier>; + + for (std::map<std::string, CZMQNotifierFactory>::const_iterator i=factories.begin(); i!=factories.end(); ++i) + { + std::map<std::string, std::string>::const_iterator j = args.find("-zmq" + i->first); + if (j!=args.end()) + { + CZMQNotifierFactory factory = i->second; + std::string address = j->second; + CZMQAbstractNotifier *notifier = factory(); + notifier->SetType(i->first); + notifier->SetAddress(address); + notifiers.push_back(notifier); + } + } + + if (!notifiers.empty()) + { + notificationInterface = new CZMQNotificationInterface(); + notificationInterface->notifiers = notifiers; + } + + return notificationInterface; +} + +// Called at startup to conditionally set up ZMQ socket(s) +bool CZMQNotificationInterface::Initialize() +{ + LogPrint("zmq", "Initialize notification interface\n"); + assert(!pcontext); + + pcontext = zmq_init(1); + + if (!pcontext) + { + zmqError("Unable to initialize context"); + return false; + } + + std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); + for (; i!=notifiers.end(); ++i) + { + CZMQAbstractNotifier *notifier = *i; + if (notifier->Initialize(pcontext)) + { + LogPrint("zmq", " Notifier %s ready (address = %s)\n", notifier->GetType(), notifier->GetAddress()); + } + else + { + LogPrint("zmq", " Notifier %s failed (address = %s)\n", notifier->GetType(), notifier->GetAddress()); + break; + } + } + + if (i!=notifiers.end()) + { + Shutdown(); + return false; + } + + return false; +} + +// Called during shutdown sequence +void CZMQNotificationInterface::Shutdown() +{ + LogPrint("zmq", "Shutdown notification interface\n"); + if (pcontext) + { + for (std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); i!=notifiers.end(); ++i) + { + CZMQAbstractNotifier *notifier = *i; + LogPrint("zmq", " Shutdown notifier %s at %s\n", notifier->GetType(), notifier->GetAddress()); + notifier->Shutdown(); + } + zmq_ctx_destroy(pcontext); + + pcontext = 0; + } +} + +void CZMQNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindex) +{ + for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); ) + { + CZMQAbstractNotifier *notifier = *i; + if (notifier->NotifyBlock(pindex)) + { + i++; + } + else + { + notifier->Shutdown(); + i = notifiers.erase(i); + } + } +} + +void CZMQNotificationInterface::SyncTransaction(const CTransaction &tx, const CBlock *pblock) +{ + for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); ) + { + CZMQAbstractNotifier *notifier = *i; + if (notifier->NotifyTransaction(tx)) + { + i++; + } + else + { + notifier->Shutdown(); + i = notifiers.erase(i); + } + } +} diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h new file mode 100644 index 0000000000..8eea15c068 --- /dev/null +++ b/src/zmq/zmqnotificationinterface.h @@ -0,0 +1,36 @@ +// 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_ZMQ_ZMQNOTIFICATIONINTERFACE_H +#define BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H + +#include "validationinterface.h" +#include <string> +#include <map> + +class CBlockIndex; +class CZMQAbstractNotifier; + +class CZMQNotificationInterface : public CValidationInterface +{ +public: + virtual ~CZMQNotificationInterface(); + + static CZMQNotificationInterface* CreateWithArguments(const std::map<std::string, std::string> &args); + + bool Initialize(); + void Shutdown(); + +protected: // CValidationInterface + void SyncTransaction(const CTransaction &tx, const CBlock *pblock); + void UpdatedBlockTip(const CBlockIndex *pindex); + +private: + CZMQNotificationInterface(); + + void *pcontext; + std::list<CZMQAbstractNotifier*> notifiers; +}; + +#endif // BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp new file mode 100644 index 0000000000..4c3eb8f2d9 --- /dev/null +++ b/src/zmq/zmqpublishnotifier.cpp @@ -0,0 +1,170 @@ +// 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 "zmqpublishnotifier.h" +#include "main.h" +#include "util.h" + +static std::multimap<std::string, CZMQAbstractPublishNotifier*> mapPublishNotifiers; + +// Internal function to send multipart message +static int zmq_send_multipart(void *sock, const void* data, size_t size, ...) +{ + va_list args; + va_start(args, size); + + while (1) + { + zmq_msg_t msg; + + int rc = zmq_msg_init_size(&msg, size); + if (rc != 0) + { + zmqError("Unable to initialize ZMQ msg"); + return -1; + } + + void *buf = zmq_msg_data(&msg); + memcpy(buf, data, size); + + data = va_arg(args, const void*); + + rc = zmq_msg_send(&msg, sock, data ? ZMQ_SNDMORE : 0); + if (rc == -1) + { + zmqError("Unable to send ZMQ msg"); + zmq_msg_close(&msg); + return -1; + } + + zmq_msg_close(&msg); + + if (!data) + break; + + size = va_arg(args, size_t); + } + return 0; +} + +bool CZMQAbstractPublishNotifier::Initialize(void *pcontext) +{ + assert(!psocket); + + // check if address is being used by other publish notifier + std::multimap<std::string, CZMQAbstractPublishNotifier*>::iterator i = mapPublishNotifiers.find(address); + + if (i==mapPublishNotifiers.end()) + { + psocket = zmq_socket(pcontext, ZMQ_PUB); + if (!psocket) + { + zmqError("Failed to create socket"); + return false; + } + + int rc = zmq_bind(psocket, address.c_str()); + if (rc!=0) + { + zmqError("Failed to bind address"); + return false; + } + + // register this notifier for the address, so it can be reused for other publish notifier + mapPublishNotifiers.insert(std::make_pair(address, this)); + return true; + } + else + { + LogPrint("zmq", " Reuse socket for address %s\n", address); + + psocket = i->second->psocket; + mapPublishNotifiers.insert(std::make_pair(address, this)); + + return true; + } +} + +void CZMQAbstractPublishNotifier::Shutdown() +{ + assert(psocket); + + int count = mapPublishNotifiers.count(address); + + // remove this notifier from the list of publishers using this address + typedef std::multimap<std::string, CZMQAbstractPublishNotifier*>::iterator iterator; + std::pair<iterator, iterator> iterpair = mapPublishNotifiers.equal_range(address); + + for (iterator it = iterpair.first; it != iterpair.second; ++it) + { + if (it->second==this) + { + mapPublishNotifiers.erase(it); + break; + } + } + + if (count == 1) + { + LogPrint("zmq", "Close socket at address %s\n", address); + int linger = 0; + zmq_setsockopt(psocket, ZMQ_LINGER, &linger, sizeof(linger)); + zmq_close(psocket); + } + + psocket = 0; +} + +bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) +{ + uint256 hash = pindex->GetBlockHash(); + LogPrint("zmq", "Publish hash block %s\n", hash.GetHex()); + 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); + return rc == 0; +} + +bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction) +{ + uint256 hash = transaction.GetHash(); + LogPrint("zmq", "Publish hash transaction %s\n", hash.GetHex()); + 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); + return rc == 0; +} + +bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) +{ + LogPrint("zmq", "Publish raw block %s\n", pindex->GetBlockHash().GetHex()); + + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + { + LOCK(cs_main); + CBlock block; + if(!ReadBlockFromDisk(block, pindex)) + { + zmqError("Can't read block from disk"); + return false; + } + + ss << block; + } + + int rc = zmq_send_multipart(psocket, "rawblock", 8, &(*ss.begin()), ss.size(), 0); + return rc == 0; +} + +bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction) +{ + uint256 hash = transaction.GetHash(); + LogPrint("zmq", "Publish raw transaction %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); + return rc == 0; +} diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h new file mode 100644 index 0000000000..44d5cbea67 --- /dev/null +++ b/src/zmq/zmqpublishnotifier.h @@ -0,0 +1,43 @@ +// 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_ZMQ_ZMQPUBLISHNOTIFIER_H +#define BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H + +#include "zmqabstractnotifier.h" + +class CBlockIndex; + +class CZMQAbstractPublishNotifier : public CZMQAbstractNotifier +{ +public: + bool Initialize(void *pcontext); + void Shutdown(); +}; + +class CZMQPublishHashBlockNotifier : public CZMQAbstractPublishNotifier +{ +public: + bool NotifyBlock(const CBlockIndex *pindex); +}; + +class CZMQPublishHashTransactionNotifier : public CZMQAbstractPublishNotifier +{ +public: + bool NotifyTransaction(const CTransaction &transaction); +}; + +class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier +{ +public: + bool NotifyBlock(const CBlockIndex *pindex); +}; + +class CZMQPublishRawTransactionNotifier : public CZMQAbstractPublishNotifier +{ +public: + bool NotifyTransaction(const CTransaction &transaction); +}; + +#endif // BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H |